Change directory structure for code integration 28/74628/1
authorSeokHoon Lee <andy.shlee@samsung.com>
Wed, 15 Jun 2016 04:16:13 +0000 (13:16 +0900)
committerSeokHoon Lee <andy.shlee@samsung.com>
Wed, 15 Jun 2016 04:16:47 +0000 (13:16 +0900)
Signed-off-by: SeokHoon Lee <andy.shlee@samsung.com>
Change-Id: Ic18ee6c8185315aff848e814ec928ec622f82cda

40 files changed:
Makefile.am
common/Makefile.am [deleted file]
common/include/mm_wfd_attrs.h [deleted file]
common/include/mm_wfd_sink_dlog.h [deleted file]
common/include/mm_wfd_sink_ini.h [deleted file]
common/include/mm_wfd_sink_wfd_enum.h [deleted file]
common/mm_wfd_attrs.c [deleted file]
common/mm_wfd_sink_ini.c [deleted file]
config/Makefile.am [deleted file]
config/Makefile.in [deleted file]
configure.ac
packaging/libmm-wfd.spec
sink/Makefile.am [deleted file]
sink/include/mm_wfd_sink.h [deleted file]
sink/include/mm_wfd_sink_manager.h [deleted file]
sink/include/mm_wfd_sink_priv.h [deleted file]
sink/include/mm_wfd_sink_util.h [deleted file]
sink/include/mm_wfd_sink_wayland.h [deleted file]
sink/mm_wfd_sink.c [deleted file]
sink/mm_wfd_sink_manager.c [deleted file]
sink/mm_wfd_sink_priv.c [deleted file]
sink/mm_wfd_sink_util.c [deleted file]
sink/mm_wfd_sink_wayland.c [deleted file]
src/Makefile.am [new file with mode: 0755]
src/include/mm_wfd_sink.h [new file with mode: 0755]
src/include/mm_wfd_sink_attrs.h [new file with mode: 0755]
src/include/mm_wfd_sink_dlog.h [new file with mode: 0755]
src/include/mm_wfd_sink_enum.h [new file with mode: 0755]
src/include/mm_wfd_sink_ini.h [new file with mode: 0755]
src/include/mm_wfd_sink_manager.h [new file with mode: 0755]
src/include/mm_wfd_sink_priv.h [new file with mode: 0755]
src/include/mm_wfd_sink_util.h [new file with mode: 0755]
src/include/mm_wfd_sink_wayland.h [new file with mode: 0755]
src/mm_wfd_sink.c [new file with mode: 0755]
src/mm_wfd_sink_attrs.c [new file with mode: 0755]
src/mm_wfd_sink_ini.c [new file with mode: 0755]
src/mm_wfd_sink_manager.c [new file with mode: 0755]
src/mm_wfd_sink_priv.c [new file with mode: 0755]
src/mm_wfd_sink_util.c [new file with mode: 0755]
src/mm_wfd_sink_wayland.c [new file with mode: 0755]

index 1c508a9813508d37f02a7601675dcfb599266ff6..295c304b309efad5bba3584fda344a4e25be58c1 100755 (executable)
@@ -1,5 +1,5 @@
 ACLOCAL_AMFLAGS='-I m4'
-SUBDIRS = common sink
+SUBDIRS = src
 
 pcfiles = mm-wfd.pc
 pkgconfigdir = $(libdir)/pkgconfig
diff --git a/common/Makefile.am b/common/Makefile.am
deleted file mode 100755 (executable)
index acc19c8..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-lib_LTLIBRARIES = libwfdcommon.la
-
-includelibwfdcommondir = $(includedir)/mmf
-
-libwfdcommon_la_SOURCES = mm_wfd_attrs.c mm_wfd_sink_ini.c
-
-libwfdcommon_la_CFLAGS =  -I$(srcdir)/include \
-        $(GLIB_CFLAGS) \
-        $(TZPLATFORM_CONFIG_CFLAGS) \
-        $(MMCOMMON_CFLAGS)
-
-libwfdcommon_la_LIBADD = $(GLIB_LIBS) \
-        $(MMCOMMON_LIBS) \
-        $(TZPLATFORM_CONFIG_LIBS) \
-        $(INIPARSER_LIBS)
diff --git a/common/include/mm_wfd_attrs.h b/common/include/mm_wfd_attrs.h
deleted file mode 100755 (executable)
index 1c6fc48..0000000
+++ /dev/null
@@ -1,132 +0,0 @@
-/*
- * libmm-wfd
- *
- * Copyright (c) 2011 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
- *
- * Contact: JongHyuk Choi <jhchoi.choi@samsung.com>, ByungWook Jang <bw.jang@samsung.com>,
- * Manoj Kumar K <manojkumar.k@samsung.com>, Hyunil Park <hyunil46.park@samsung.com>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-#ifndef __MM_WFD_ATTRS_H__
-#define __MM_WFD_ATTRS_H__
-
-#include <string.h>
-#include <glib.h>
-#include <mm_message.h>
-#include <mm_error.h>
-#include <mm_types.h>
-#include <mm_attrs_private.h>
-#include <mm_attrs.h>
-#include <mm_debug.h>
-
-/* general */
-#ifndef ARRAY_SIZE
-#define ARRAY_SIZE(arr)  (sizeof(arr) / sizeof((arr)[0]))
-#endif
-#define MMWFD_MAX_INT (2147483647)
-
-/**
- * Enumeration for attribute values types.
- */
-typedef enum {
-       MM_WFD_ATTRS_TYPE_INVALID = -1,        /**< Type is invalid */
-       MM_WFD_ATTRS_TYPE_INT,                 /**< Integer type */
-       MM_WFD_ATTRS_TYPE_DOUBLE,              /**< Double type */
-       MM_WFD_ATTRS_TYPE_STRING,              /**< UTF-8 String type */
-       MM_WFD_ATTRS_TYPE_DATA,                /**< Pointer type */
-       MM_WFD_ATTRS_TYPE_ARRAY,               /**< Array type */
-       MM_WFD_ATTRS_TYPE_RANGE,               /**< Range type */
-       MM_WFD_ATTRS_TYPE_NUM,                 /**< Number of attribute type */
-} MMWfdAttrsType;
-
-/**
- * Enumeration for attribute validation type.
- */
-typedef enum {
-       MM_WFD_ATTRS_VALID_TYPE_INVALID = -1,       /**< Invalid validation type */
-       MM_WFD_ATTRS_VALID_TYPE_NONE,               /**< Do not check validity */
-       MM_WFD_ATTRS_VALID_TYPE_INT_ARRAY,          /**< validity checking type of integer array */
-       MM_WFD_ATTRS_VALID_TYPE_INT_RANGE,          /**< validity checking type of integer range */
-       MM_WFD_ATTRS_VALID_TYPE_DOUBLE_ARRAY,       /**< validity checking type of double array */
-       MM_WFD_ATTRS_VALID_TYPE_DOUBLE_RANGE,       /**< validity checking type of double range */
-} MMWfdAttrsValidType;
-
-/**
- * Enumeration for attribute access flag.
- */
-typedef enum {
-       MM_WFD_ATTRS_FLAG_NONE = 0,              /**< None flag is set */
-       MM_WFD_ATTRS_FLAG_READABLE = 1 << 0,     /**< Readable */
-       MM_WFD_ATTRS_FLAG_WRITABLE = 1 << 1,     /**< Writable */
-       MM_WFD_ATTRS_FLAG_MODIFIED = 1 << 2,     /**< Modified */
-
-       MM_WFD_ATTRS_FLAG_RW = MM_WFD_ATTRS_FLAG_READABLE | MM_WFD_ATTRS_FLAG_WRITABLE, /**< Readable and Writable */
-} MMWfdAttrsFlag;
-
-/**
- * Attribute validity structure
- */
-typedef struct {
-       MMWfdAttrsType type;
-       MMWfdAttrsValidType validity_type;
-       MMWfdAttrsFlag flag;
-       /**
-         * a union that describes validity of the attribute.
-         * Only when type is 'MM_ATTRS_TYPE_INT' or 'MM_ATTRS_TYPE_DOUBLE',
-         * the attribute can have validity.
-        */
-       union {
-               /**
-                  * Validity structure for integer array.
-                */
-               struct {
-                       int *array;  /**< a pointer of array */
-                       int count;   /**< size of array */
-                       int d_val;
-               } int_array;
-               /**
-                  * Validity structure for integer range.
-                */
-               struct {
-                       int min;   /**< minimum range */
-                       int max;   /**< maximum range */
-                       int d_val;
-               } int_range;
-               /**
-               * Validity structure for double array.
-               */
-               struct {
-                       double    *array;  /**< a pointer of array */
-                       int    count;   /**< size of array */
-                       double d_val;
-               } double_array;
-               /**
-               * Validity structure for double range.
-               */
-               struct {
-                       double   min;   /**< minimum range */
-                       double   max;   /**< maximum range */
-                       double d_val;
-               } double_range;
-       };
-} MMWfdAttrsInfo;
-
-MMHandleType _mmwfd_construct_attribute(MMHandleType hwfd);
-void  _mmwfd_deconstruct_attribute(MMHandleType hwfd);
-int _mmwfd_set_attribute(MMHandleType hwfd,  char **err_atr_name, const char *attribute_name, va_list args_list);
-int _mmwfd_get_attributes_info(MMHandleType handle,  const char *attribute_name, MMWfdAttrsInfo *dst_info);
-int _mmwfd_get_attribute(MMHandleType handle,  char **err_attr_name, const char *attribute_name, va_list args_list);
-#endif /* __MM_WFD_ATTRS_H__ */
\ No newline at end of file
diff --git a/common/include/mm_wfd_sink_dlog.h b/common/include/mm_wfd_sink_dlog.h
deleted file mode 100755 (executable)
index 58082e8..0000000
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
-* 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 FONT_COLOR_RESET    "\033[0m"
-#define FONT_COLOR_RED      "\033[31m"
-#define FONT_COLOR_GREEN    "\033[32m"
-#define FONT_COLOR_YELLOW   "\033[33m"
-#define FONT_COLOR_BLUE     "\033[34m"
-#define FONT_COLOR_PURPLE   "\033[35m"
-#define FONT_COLOR_CYAN     "\033[36m"
-#define FONT_COLOR_GRAY     "\033[37m"
-
-#define wfd_sink_debug(fmt, arg...) do { \
-               LOGD(FONT_COLOR_RESET""fmt"", ##arg);     \
-       } while (0)
-
-#define wfd_sink_info(fmt, arg...) do { \
-               LOGI(FONT_COLOR_GREEN""fmt""FONT_COLOR_RESET, ##arg);     \
-       } while (0)
-
-#define wfd_sink_error(fmt, arg...) do { \
-               LOGE(FONT_COLOR_RED""fmt""FONT_COLOR_RESET, ##arg);     \
-       } while (0)
-
-#define wfd_sink_warning(fmt, arg...) do { \
-               LOGW(FONT_COLOR_YELLOW""fmt""FONT_COLOR_RESET, ##arg);     \
-       } while (0)
-
-#define wfd_sink_debug_fenter() do { \
-               LOGD(FONT_COLOR_RESET"<Enter>");     \
-       } while (0)
-
-#define wfd_sink_debug_fleave() do { \
-               LOGD(FONT_COLOR_RESET"<Leave>");     \
-       } while (0)
-
-#define wfd_sink_error_fenter() do { \
-               LOGE(FONT_COLOR_RED"NO-ERROR : <Enter>"FONT_COLOR_RESET);     \
-       } while (0)
-
-#define wfd_sink_error_fleave() do { \
-               LOGE(FONT_COLOR_RED"NO-ERROR : <Leave>"FONT_COLOR_RESET);     \
-       } while (0)
-
-#define wfd_sink_sucure_info(fmt, arg...) do { \
-               SECURE_LOGI(FONT_COLOR_GREEN""fmt""FONT_COLOR_RESET, ##arg);     \
-       } while (0)
-
-#define wfd_sink_return_if_fail(expr)  \
-       if(!(expr)) {   \
-               wfd_sink_error(FONT_COLOR_RED"failed [%s]\n"FONT_COLOR_RESET, #expr);   \
-               return; \
-       }
-
-#define wfd_sink_return_val_if_fail(expr, val) \
-       if (!(expr)) {  \
-               wfd_sink_error(FONT_COLOR_RED"failed [%s]\n"FONT_COLOR_RESET, #expr);   \
-               return val; \
-       }
-
-#define wfd_sink_assert_not_reached() \
-       { \
-               wfd_sink_error(FONT_COLOR_RED"assert_not_reached()"FONT_COLOR_RESET); \
-               assert(0); \
-       }
-
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-#endif /* __MM_WFD_SINK_DLOG_H__ */
-
diff --git a/common/include/mm_wfd_sink_ini.h b/common/include/mm_wfd_sink_ini.h
deleted file mode 100755 (executable)
index 73da585..0000000
+++ /dev/null
@@ -1,353 +0,0 @@
-/*
- * libmm-wfd
- *
- * Copyright (c) 2011 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
- *
- * Contact: JongHyuk Choi <jhchoi.choi@samsung.com>, ByungWook Jang <bw.jang@samsung.com>,
- * Manoj Kumar K <manojkumar.k@samsung.com>, Hyunil Park <hyunil46.park@samsung.com>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-#ifndef __MM_WFD_SINK_INI_H__
-#define __MM_WFD_SINK_INI_H__
-
-#include <glib.h>
-#include <tzplatform_config.h>
-#include "mm_wfd_sink_wfd_enum.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-enum WFDSinkINIProbeFlags
-{
-       WFD_SINK_INI_PROBE_DEFAULT = 0,
-       WFD_SINK_INI_PROBE_TIMESTAMP = (1 << 0),
-       WFD_SINK_INI_PROBE_BUFFERSIZE = (1 << 1),
-       WFD_SINK_INI_PROBE_CAPS = (1 << 2),
-       WFD_SINK_INI_PROBE_BUFFER_DURATION = (1 << 3),
-};
-
-#define MM_WFD_SINK_INI_DEFAULT_PATH   SYSCONFDIR"/multimedia/mmfw_wfd_sink.ini"
-
-#define WFD_SINK_INI_MAX_STRLEN        256
-#define WFD_SINK_INI_MAX_ELEMENT       10
-
-/* NOTE : MMPlayer has no initalizing API for library itself
- * so we cannot decide when those ini values to be released.
- * this is the reason of all string items are static array.
- * make it do with malloc when MMPlayerInitialize() API created
- * before that time, we should be careful with size limitation
- * of each string item.
- */
-typedef struct __mm_wfd_sink_ini {
-       /* general */
-       gchar gst_param[5][WFD_SINK_INI_MAX_STRLEN];
-       gboolean generate_dot;
-       gboolean enable_pad_probe;
-       gint state_change_timeout;
-       gboolean set_debug_property;
-       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;
-       gboolean enable_wfdsrc_pad_probe;
-
-       /* pipeline */
-       gchar name_of_source[WFD_SINK_INI_MAX_STRLEN];
-       gchar name_of_tsdemux[WFD_SINK_INI_MAX_STRLEN];
-       gchar name_of_audio_hdcp[WFD_SINK_INI_MAX_STRLEN];
-       gchar name_of_aac_parser[WFD_SINK_INI_MAX_STRLEN];
-       gchar name_of_aac_decoder[WFD_SINK_INI_MAX_STRLEN];
-       gchar name_of_ac3_parser[WFD_SINK_INI_MAX_STRLEN];
-       gchar name_of_ac3_decoder[WFD_SINK_INI_MAX_STRLEN];
-       gchar name_of_lpcm_converter[WFD_SINK_INI_MAX_STRLEN];
-       gchar name_of_lpcm_filter[WFD_SINK_INI_MAX_STRLEN];
-       gchar name_of_audio_resampler[WFD_SINK_INI_MAX_STRLEN];
-       gchar name_of_audio_volume[WFD_SINK_INI_MAX_STRLEN];
-       gchar name_of_audio_sink[WFD_SINK_INI_MAX_STRLEN];
-
-       gchar name_of_video_hdcp[WFD_SINK_INI_MAX_STRLEN];
-       gchar name_of_video_parser[WFD_SINK_INI_MAX_STRLEN];
-       gchar name_of_video_capssetter[WFD_SINK_INI_MAX_STRLEN];
-       gchar name_of_video_decoder[WFD_SINK_INI_MAX_STRLEN];
-       gchar name_of_video_converter[WFD_SINK_INI_MAX_STRLEN];
-       gchar name_of_video_filter[WFD_SINK_INI_MAX_STRLEN];
-       gchar name_of_video_sink[WFD_SINK_INI_MAX_STRLEN];
-       gchar name_of_video_evas_sink[WFD_SINK_INI_MAX_STRLEN];
-
-       /* audio parameter for reponse of M3 request */
-       guint audio_codec;
-       guint audio_latency;
-       guint audio_channel;
-       guint audio_sampling_frequency;
-
-       /* video parameter for reponse of M3 request */
-       guint video_codec;
-       guint video_native_resolution;
-       guint video_cea_support;
-       guint video_vesa_support;
-       guint video_hh_support;
-       guint video_profile;
-       guint video_level;
-       guint video_latency;
-       gint video_vertical_resolution;
-       gint video_horizontal_resolution;
-       gint video_minimum_slicing;
-       gint video_slice_enc_param;
-       gint video_framerate_control_support;
-
-       /* hdcp parameter for reponse of M3 request */
-       gint hdcp_content_protection;
-       gint hdcp_port_no;
-} mm_wfd_sink_ini_t;
-
-
-/*Default sink ini values*/
-/* General*/
-#define DEFAULT_GST_PARAM      ""
-#define DEFAULT_GENERATE_DOT   FALSE
-#define DEFAULT_ENABLE_PAD_PROBE       FALSE
-#define DEFAULT_STATE_CHANGE_TIMEOUT 5 /* sec */
-#define DEFAULT_SET_DEBUG_PROPERTY     TRUE
-#define DEFAULT_ENABLE_ASM     FALSE
-#define DEFAULT_JITTER_BUFFER_LATENCY 10 /* msec */
-#define DEFAULT_ENABLE_RETRANSMISSION  FALSE
-#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
-
-/* Pipeline */
-#define DEFAULT_NAME_OF_SOURCE "wfdsrc"
-#define DEFAULT_NAME_OF_TSDEMUX ""
-#define DEFAULT_NAME_OF_AUDIO_HDCP ""
-#define DEFAULT_NAME_OF_AAC_PARSER ""
-#define DEFAULT_NAME_OF_AAC_DECODER ""
-#define DEFAULT_NAME_OF_AC3_PARSER ""
-#define DEFAULT_NAME_OF_AC3_DECODER ""
-#define DEFAULT_NAME_OF_LPCM_CONVERTER ""
-#define DEFAULT_NAME_OF_LPCM_FILTER ""
-#define DEFAULT_NAME_OF_AUDIO_RESAMPLER ""
-#define DEFAULT_NAME_OF_AUDIO_VOLUME ""
-#define DEFAULT_NAME_OF_AUDIO_SPLITTER ""
-#define DEFAULT_NAME_OF_AUDIO_SINK ""
-#define DEFAULT_NAME_OF_VIDEO_HDCP ""
-#define DEFAULT_NAME_OF_VIDEO_PARSER ""
-#define DEFAULT_NAME_OF_VIDEO_CAPSSETTER ""
-#define DEFAULT_NAME_OF_VIDEO_DECODER ""
-#define DEFAULT_NAME_OF_VIDEO_CONVERTER ""
-#define DEFAULT_NAME_OF_VIDEO_FILTER ""
-#define DEFAULT_NAME_OF_VIDEO_SINK ""
-#define DEFAULT_NAME_OF_EVAS_VIDEO_SINK ""
-
-/* Audio */
-#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
-
-/* Video */
-#define DEFAULT_VIDEO_CODEC WFD_VIDEO_H264
-#define DEFAULT_VIDEO_NATIVE_RESOLUTION 0x20
-/* CEA :  WFD_CEA_640x480P60  | WFD_CEA_720x480P60 |WFD_CEA_720x576P50 |WFD_CEA_1280x720P30 |
-       WFD_CEA_1280x720P25 | WFD_CEA_1280x720P24 */
-#define DEFAULT_VIDEO_CEA_SUPPORT 0x84ab
-/* VESA : WFD_VESA_800x600P30 */
-#define DEFAULT_VIDEO_VESA_SUPPORT 0x1
-/* HH : WFD_HH_800x480P30 | WFD_HH_854x480P30 | WFD_HH_864x480P30 | WFD_HH_640x360P30 | WFD_HH_960x540P30 | WFD_HH_848x480P30 */
-#define DEFAULT_VIDEO_HH_SUPPORT 0x555
-#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 720
-#define DEFAULT_VIDEO_HORIZONTAL_RESOLUTION 1280
-#define DEFAULT_VIDEO_MIN_SLICESIZE 0
-#define DEFAULT_VIDEO_SLICE_ENC_PARAM 200
-#define DEFAULT_VIDEO_FRAMERATE_CONTROL 11
-
-/* HDCP */
-#define DEFAULT_HDCP_CONTENT_PROTECTION 0x0
-#define DEFAULT_HDCP_PORT_NO 0
-
-
-#define MM_WFD_SINK_DEFAULT_INI \
-" \
-[general]\n\
-; parameters for initializing gstreamer\n\
-; DEFAULT SET(--gst-debug=2, *wfd*:5)\n\
-gstparam1 = --gst-debug=2, *wfd*:5, *wfdtsdemux:1, *wfdrtpbuffer:1\n\
-gstparam2 =\n\
-gstparam3 =\n\
-gstparam4 =\n\
-gstparam5 =\n\
-\n\
-; generating dot file representing pipeline state\n\
-; do export GST_DEBUG_DUMP_DOT_DIR=[dot file path] in the shell\n\
-generate dot = no\n\
-\n\
-; enable pad probe\n\
-enable pad probe = no\n\
-\n\
-; enable wfdsrc inner pad probe\n\
-enable wfdsrc pad probe = no\n\
-\n\
-; enable ts data dump(eg. /var/tmp/*.ts)\n\
-enable ts data dump = no\n\
-\n\
-; allowed timeout for changing pipeline state\n\
-state change timeout = 5 ; sec\n\
-\n\
-; set debug property to wfdsrc plugin for debugging rtsp message\n\
-set debug property = yes\n\
-\n\
-; for asm function enable = yes, disable = no\n\
-enable asm = no\n\
-\n\
-; 0: default value set by wfdsrc element, other: user define value.\n\
-jitter buffer latency=10\n\
-\n\
-; for retransmission request enable = yes, disable = no\n\
-enable retransmission = no\n\
-\n\
-; for reset basetime, enable = yes, disable = no\n\
-enable reset basetime = yes\n\
-\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\
-wfdsrc element = wfdsrc\n\
-\n\
-tsdemux element = wfdtsdemux\n\
-\n\
-aac parser element = aacparse\n\
-\n\
-aac decoder element = avdec_aac\n\
-\n\
-ac3 parser element = ac3parse\n\
-\n\
-ac3 decoder element =\n\
-\n\
-lpcm converter element =\n\
-\n\
-lpcm filter element = capsfilter\n\
-\n\
-audio resampler element = audioconvert\n\
-\n\
-audio volume element =\n\
-\n\
-audio sink element = pulsesink\n\
-\n\
-video parser element = h264parse\n\
-\n\
-video capssetter element = capssetter\n\
-\n\
-video decoder element = avdec_h264;sprddec_h264;omxh264dec\n\
-\n\
-video converter element =\n\
-\n\
-video filter element =\n\
-\n\
-video sink element = waylandsink;xvimagesink\n\
-\n\
-\n\
-\n\
-[audio param]\n\
-; 0x1: LPCM, 0x2: aac, 0x4: ac3\n\
-;default aac and LPCM\n\
-audio codec=0x3\n\
-\n\
-audio latency=0x0\n\
-\n\
-;0x1 : 48000khz, 0x2: 44100khz\n\
-audio sampling frequency=0x3\n\
-\n\
-; 0x1:2 channels, 0x2:4 channels, 0x4:6channels, 0x8:8channels\n\
-audio channels=0x1\n\
-\n\
-\n\
-\n\
-[video param]\n\
-; 0: H264CBP 1: H264CHP\n\
-video codec=0x1\n\
-\n\
-video native resolution = 0x20\n\
-\n\
-video cea support=0x842b\n\
-\n\
-video vesa support=0x1\n\
-\n\
-video hh support=0x555\n\
-\n\
-; 0x1:base, 0x2:high\n\
-video profile=0x1\n\
-\n\
-; 0x1:level_3_1, 0x2:level_3_2, 0x4:level_4, 0x8:level_4_1, 0x10:level_4_2\n\
-video level=0x2\n\
-\n\
-video latency=0x0\n\
-\n\
-video vertical resolution=720\n\
-\n\
-video horizontal resolution=1280\n\
-\n\
-video minimum slicesize=0\n\
-\n\
-video slice encoding params=200\n\
-\n\
-video framerate control support=11\n\
-\n\
-\n\
-\n\
-[hdcp param]\n\
-;0x0:none, 0x1:HDCP_2.0, 0x2:HDCP_2.1\n\
-hdcp content protection=0x0\n\
-\n\
-hdcp port no=0\n\
-\n\
-"
-
-int
-mm_wfd_sink_ini_load(mm_wfd_sink_ini_t *ini);
-
-int
-mm_wfd_sink_ini_unload(mm_wfd_sink_ini_t *ini);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/common/include/mm_wfd_sink_wfd_enum.h b/common/include/mm_wfd_sink_wfd_enum.h
deleted file mode 100755 (executable)
index c88cc8b..0000000
+++ /dev/null
@@ -1,145 +0,0 @@
-/*
- * Enumeration for WFD
- *
- * Copyright (c) 2011 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
- *
- * Contact: JongHyuk Choi <jhchoi.choi@samsung.com>, ByungWook Jang <bw.jang@samsung.com>,
- * Maksym Ukhanov <m.ukhanov@samsung.com>, Hyunjun Ko <zzoon.ko@samsung.com>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-#ifndef _MM_WFD_SINK_WFD_ENUM_H_
-#define _MM_WFD_SINK_WFD_ENUM_H_
-
-typedef enum {
-       WFD_AUDIO_UNKNOWN       = 0,
-       WFD_AUDIO_LPCM          = (1 << 0),
-       WFD_AUDIO_AAC           = (1 << 1),
-       WFD_AUDIO_AC3           = (1 << 2)
-} WFDAudioFormats;
-
-typedef enum {
-       WFD_FREQ_UNKNOWN = 0,
-       WFD_FREQ_44100   = (1 << 0),
-       WFD_FREQ_48000   = (1 << 1)
-} WFDAudioFreq;
-
-typedef enum {
-       WFD_CHANNEL_UNKNOWN = 0,
-       WFD_CHANNEL_2           = (1 << 0),
-       WFD_CHANNEL_4           = (1 << 1),
-       WFD_CHANNEL_6           = (1 << 2),
-       WFD_CHANNEL_8           = (1 << 3)
-} WFDAudioChannels;
-
-
-typedef enum {
-       WFD_VIDEO_UNKNOWN = 0,
-       WFD_VIDEO_H264    = (1 << 0)
-} WFDVideoCodecs;
-
-typedef enum {
-       WFD_VIDEO_CEA_RESOLUTION = 0,
-       WFD_VIDEO_VESA_RESOLUTION,
-       WFD_VIDEO_HH_RESOLUTION
-} WFDVideoNativeResolution;
-
-typedef enum {
-       WFD_CEA_UNKNOWN         = 0,
-       WFD_CEA_640x480P60      = (1 << 0),
-       WFD_CEA_720x480P60      = (1 << 1),
-       WFD_CEA_720x480I60      = (1 << 2),
-       WFD_CEA_720x576P50      = (1 << 3),
-       WFD_CEA_720x576I50      = (1 << 4),
-       WFD_CEA_1280x720P30     = (1 << 5),
-       WFD_CEA_1280x720P60     = (1 << 6),
-       WFD_CEA_1920x1080P30 = (1 << 7),
-       WFD_CEA_1920x1080P60 = (1 << 8),
-       WFD_CEA_1920x1080I60 = (1 << 9),
-       WFD_CEA_1280x720P25     = (1 << 10),
-       WFD_CEA_1280x720P50     = (1 << 11),
-       WFD_CEA_1920x1080P25 = (1 << 12),
-       WFD_CEA_1920x1080P50 = (1 << 13),
-       WFD_CEA_1920x1080I50 = (1 << 14),
-       WFD_CEA_1280x720P24     = (1 << 15),
-       WFD_CEA_1920x1080P24 = (1 << 16)
-} WFDVideoCEAResolution;
-
-typedef enum {
-       WFD_VESA_UNKNOWN                = 0,
-       WFD_VESA_800x600P30     = (1 << 0),
-       WFD_VESA_800x600P60             = (1 << 1),
-       WFD_VESA_1024x768P30    = (1 << 2),
-       WFD_VESA_1024x768P60    = (1 << 3),
-       WFD_VESA_1152x864P30    = (1 << 4),
-       WFD_VESA_1152x864P60    = (1 << 5),
-       WFD_VESA_1280x768P30    = (1 << 6),
-       WFD_VESA_1280x768P60    = (1 << 7),
-       WFD_VESA_1280x800P30    = (1 << 8),
-       WFD_VESA_1280x800P60    = (1 << 9),
-       WFD_VESA_1360x768P30    = (1 << 10),
-       WFD_VESA_1360x768P60    = (1 << 11),
-       WFD_VESA_1366x768P30    = (1 << 12),
-       WFD_VESA_1366x768P60    = (1 << 13),
-       WFD_VESA_1280x1024P30   = (1 << 14),
-       WFD_VESA_1280x1024P60   = (1 << 15),
-       WFD_VESA_1400x1050P30   = (1 << 16),
-       WFD_VESA_1400x1050P60   = (1 << 17),
-       WFD_VESA_1440x900P30    = (1 << 18),
-       WFD_VESA_1440x900P60    = (1 << 19),
-       WFD_VESA_1600x900P30    = (1 << 20),
-       WFD_VESA_1600x900P60    = (1 << 21),
-       WFD_VESA_1600x1200P30   = (1 << 22),
-       WFD_VESA_1600x1200P60   = (1 << 23),
-       WFD_VESA_1680x1024P30   = (1 << 24),
-       WFD_VESA_1680x1024P60   = (1 << 25),
-       WFD_VESA_1680x1050P30   = (1 << 26),
-       WFD_VESA_1680x1050P60   = (1 << 27),
-       WFD_VESA_1920x1200P30   = (1 << 28),
-       WFD_VESA_1920x1200P60   = (1 << 29)
-} WFDVideoVESAResolution;
-
-typedef enum {
-       WFD_HH_UNKNOWN          = 0,
-       WFD_HH_800x480P30       = (1 << 0),
-       WFD_HH_800x480P60       = (1 << 1),
-       WFD_HH_854x480P30       = (1 << 2),
-       WFD_HH_854x480P60       = (1 << 3),
-       WFD_HH_864x480P30       = (1 << 4),
-       WFD_HH_864x480P60       = (1 << 5),
-       WFD_HH_640x360P30       = (1 << 6),
-       WFD_HH_640x360P60       = (1 << 7),
-       WFD_HH_960x540P30       = (1 << 8),
-       WFD_HH_960x540P60       = (1 << 9),
-       WFD_HH_848x480P30       = (1 << 10),
-       WFD_HH_848x480P60       = (1 << 11)
-} WFDVideoHHResolution;
-
-typedef enum {
-       WFD_H264_UNKNOWN_PROFILE = 0,
-       WFD_H264_BASE_PROFILE   = (1 << 0),
-       WFD_H264_HIGH_PROFILE   = (1 << 1)
-} WFDVideoH264Profile;
-
-typedef enum {
-       WFD_H264_LEVEL_UNKNOWN = 0,
-       WFD_H264_LEVEL_3_1   = (1 << 0),
-       WFD_H264_LEVEL_3_2   = (1 << 1),
-       WFD_H264_LEVEL_4       = (1 << 2),
-       WFD_H264_LEVEL_4_1   = (1 << 3),
-       WFD_H264_LEVEL_4_2   = (1 << 4)
-} WFDVideoH264Level;
-
-#endif /*_MM_WFD_SINK_WFD_ENUM_H_*/
diff --git a/common/mm_wfd_attrs.c b/common/mm_wfd_attrs.c
deleted file mode 100755 (executable)
index e42c914..0000000
+++ /dev/null
@@ -1,552 +0,0 @@
-/*
- * libmm-wfd
- *
- * Copyright (c) 2011 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
- *
- * Contact: JongHyuk Choi <jhchoi.choi@samsung.com>, ByungWook Jang <bw.jang@samsung.com>,
- * Manoj Kumar K <manojkumar.k@samsung.com>, Hyunil Park <hyunil46.park@samsung.com>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-#include "mm_wfd_attrs.h"
-
-typedef struct {
-       char *name;
-       int value_type;
-       int flags;           /* r, w */
-       void *default_value;
-       int valid_type;
-       int value_min;
-       int value_max;
-} MMWfdAttrsSpec;
-
-/*static gboolean __mmwfd_apply_attribute(MMHandleType handle, const char *attribute_name); */
-
-MMHandleType
-_mmwfd_construct_attribute(MMHandleType handle)
-{
-       int idx = 0;
-       MMHandleType attrs = 0;
-       int num_of_attrs = 0;
-       mmf_attrs_construct_info_t *base = NULL;
-
-       debug_fenter();
-
-       return_val_if_fail(handle, (MMHandleType) NULL);
-
-       MMWfdAttrsSpec wfd_attrs[] = {
-               {
-                       (char *)"server_ip",
-                       MM_ATTRS_TYPE_STRING,
-                       MM_ATTRS_FLAG_RW,
-                       (void *)"127.0.0.1",
-                       MM_ATTRS_VALID_TYPE_NONE,
-                       0,
-                       0
-               },
-
-               {
-                       (char *)"server_port",
-                       MM_ATTRS_TYPE_STRING,
-                       MM_ATTRS_FLAG_RW,
-                       (void *)"8554",
-                       MM_ATTRS_VALID_TYPE_NONE,
-                       0,
-                       0
-               },
-
-               {
-                       (char *)"max_client_count",
-                       MM_ATTRS_TYPE_INT,
-                       MM_ATTRS_FLAG_RW,
-                       (void *)1,
-                       MM_ATTRS_VALID_TYPE_INT_RANGE,
-                       0,
-                       10
-               },
-               /* Initialized with invalid native type, if a valid value is set then only this atribute will be considered */
-               {
-                       (char *)"native_resolution",
-                       MM_ATTRS_TYPE_INT,
-                       MM_ATTRS_FLAG_RW,
-                       (void *)0,
-                       MM_ATTRS_VALID_TYPE_INT_RANGE,
-                       0,
-                       3
-               },
-               /* Initialized with invalid resolution, if a valid value is set then only this atribute will be considered */
-               {
-                       (char *)"prefered_resolutions",
-                       MM_ATTRS_TYPE_INT,
-                       MM_ATTRS_FLAG_RW,
-                       (void *)2147483647,
-                       MM_ATTRS_VALID_TYPE_INT_RANGE,
-                       0,
-                       2147483647
-               },
-               /* Initialized with invalid uibc option, if a valid value is set then only this atribute will be considered */
-               {
-                       (char *)"set_hdcp",
-                       MM_ATTRS_TYPE_INT,
-                       MM_ATTRS_FLAG_RW,
-                       (void *)2,
-                       MM_ATTRS_VALID_TYPE_INT_RANGE,
-                       0,
-                       2
-               },
-               {
-                       (char *)"display_rotate",
-                       MM_ATTRS_TYPE_INT,
-                       MM_ATTRS_FLAG_RW,
-                       (void *)0,
-                       MM_ATTRS_VALID_TYPE_INT_RANGE,
-                       0,
-                       3
-               },
-               {
-                       (char *)"display_src_crop_x",
-                       MM_ATTRS_TYPE_INT,
-                       MM_ATTRS_FLAG_RW,
-                       (void *) 0,
-                       MM_ATTRS_VALID_TYPE_INT_RANGE,
-                       0,
-                       4096
-               },
-               {
-                       (char *)"display_src_crop_y",
-                       MM_ATTRS_TYPE_INT,
-                       MM_ATTRS_FLAG_RW,
-                       (void *) 0,
-                       MM_ATTRS_VALID_TYPE_INT_RANGE,
-                       0,
-                       4096
-               },
-               {
-                       (char *)"display_src_crop_width",
-                       MM_ATTRS_TYPE_INT,
-                       MM_ATTRS_FLAG_RW,
-                       (void *) 0,
-                       MM_ATTRS_VALID_TYPE_INT_RANGE,
-                       0,
-                       4096
-               },
-               {
-                       (char *)"display_src_crop_height",
-                       MM_ATTRS_TYPE_INT,
-                       MM_ATTRS_FLAG_RW,
-                       (void *) 0,
-                       MM_ATTRS_VALID_TYPE_INT_RANGE,
-                       0,
-                       4096
-               },
-               {
-                       (char *)"display_roi_x",
-                       MM_ATTRS_TYPE_INT,
-                       MM_ATTRS_FLAG_RW,
-                       (void *) 0,
-                       MM_ATTRS_VALID_TYPE_INT_RANGE,
-                       0,
-                       4096
-               },
-               {
-                       (char *)"display_roi_y",
-                       MM_ATTRS_TYPE_INT,
-                       MM_ATTRS_FLAG_RW,
-                       (void *) 0,
-                       MM_ATTRS_VALID_TYPE_INT_RANGE,
-                       0,
-                       4096
-               },
-               {
-                       (char *)"display_roi_width",
-                       MM_ATTRS_TYPE_INT,
-                       MM_ATTRS_FLAG_RW,
-                       (void *) 480,
-                       MM_ATTRS_VALID_TYPE_INT_RANGE,
-                       0,
-                       4096
-               },
-               {
-                       (char *)"display_roi_height",
-                       MM_ATTRS_TYPE_INT,
-                       MM_ATTRS_FLAG_RW,
-                       (void *) 800,
-                       MM_ATTRS_VALID_TYPE_INT_RANGE,
-                       0,
-                       4096
-               },
-               {
-                       (char *)"display_roi_mode",
-                       MM_ATTRS_TYPE_INT,
-                       MM_ATTRS_FLAG_RW,
-                       (void *) MM_DISPLAY_METHOD_CUSTOM_ROI_FULL_SCREEN,
-                       MM_ATTRS_VALID_TYPE_INT_RANGE,
-                       MM_DISPLAY_METHOD_CUSTOM_ROI_FULL_SCREEN,
-                       MM_DISPLAY_METHOD_CUSTOM_ROI_LETER_BOX
-               },
-               {
-                       (char *)"display_rotation",
-                       MM_ATTRS_TYPE_INT,
-                       MM_ATTRS_FLAG_RW,
-                       (void *) MM_DISPLAY_ROTATION_NONE,
-                       MM_ATTRS_VALID_TYPE_INT_RANGE,
-                       MM_DISPLAY_ROTATION_NONE,
-                       MM_DISPLAY_ROTATION_270
-               },
-               {
-                       (char *)"display_visible",
-                       MM_ATTRS_TYPE_INT,
-                       MM_ATTRS_FLAG_RW,
-                       (void *) TRUE,
-                       MM_ATTRS_VALID_TYPE_INT_RANGE,
-                       0,
-                       1
-               },
-               {
-                       (char *)"display_method",
-                       MM_ATTRS_TYPE_INT,
-                       MM_ATTRS_FLAG_RW,
-                       (void *) MM_DISPLAY_METHOD_LETTER_BOX,
-                       MM_ATTRS_VALID_TYPE_INT_RANGE,
-                       MM_DISPLAY_METHOD_LETTER_BOX,
-                       MM_DISPLAY_METHOD_CUSTOM_ROI
-               },
-               {
-                       (char *)"display_overlay",
-                       MM_ATTRS_TYPE_DATA,
-                       MM_ATTRS_FLAG_RW,
-                       (void *) NULL,
-                       MM_ATTRS_VALID_TYPE_NONE,
-                       0,
-                       0
-               },
-               {
-                       (char *)"display_overlay_user_data",
-                       MM_ATTRS_TYPE_DATA,
-                       MM_ATTRS_FLAG_RW,
-                       (void *) NULL,
-                       MM_ATTRS_VALID_TYPE_NONE,
-                       0,
-                       0
-               },
-               {
-                       (char *)"display_zoom",
-                       MM_ATTRS_TYPE_DOUBLE,
-                       MM_ATTRS_FLAG_RW,
-                       (void *) 1,
-                       MM_ATTRS_VALID_TYPE_DOUBLE_RANGE,
-                       1.0,
-                       9.0
-               },
-               {
-                       (char *)"display_surface_type",
-                       MM_ATTRS_TYPE_INT,
-                       MM_ATTRS_FLAG_RW,
-                       (void *) MM_DISPLAY_SURFACE_OVERLAY,
-                       MM_ATTRS_VALID_TYPE_INT_RANGE,
-                       MM_DISPLAY_SURFACE_OVERLAY,
-                       MM_DISPLAY_SURFACE_REMOTE
-               },
-               {
-                       (char *)"display_width",   /* dest width of fimcconvert ouput */
-                       MM_ATTRS_TYPE_INT,
-                       MM_ATTRS_FLAG_RW,
-                       (void *) 0,
-                       MM_ATTRS_VALID_TYPE_INT_RANGE,
-                       0,
-                       4096
-               },
-               {
-                       (char *)"display_height",   /* dest height of fimcconvert ouput */
-                       MM_ATTRS_TYPE_INT,
-                       MM_ATTRS_FLAG_RW,
-                       (void *) 0,
-                       MM_ATTRS_VALID_TYPE_INT_RANGE,
-                       0,
-                       4096
-               },
-               {
-                       (char *)"display_evas_do_scaling",
-                       MM_ATTRS_TYPE_INT,
-                       MM_ATTRS_FLAG_RW,
-                       (void *) TRUE,
-                       MM_ATTRS_VALID_TYPE_INT_RANGE,
-                       FALSE,
-                       TRUE
-               },
-               {
-                       (char *)"display_x",
-                       MM_ATTRS_TYPE_INT,
-                       MM_ATTRS_FLAG_RW,
-                       (void *) 0,
-                       MM_ATTRS_VALID_TYPE_INT_RANGE,
-                       0,
-                       4096
-               },
-               {
-                       (char *)"display_y",
-                       MM_ATTRS_TYPE_INT,
-                       MM_ATTRS_FLAG_RW,
-                       (void *) 0,
-                       MM_ATTRS_VALID_TYPE_INT_RANGE,
-                       0,
-                       4096
-               },
-               {
-                       (char *)"hdcp_version",
-                       MM_ATTRS_TYPE_INT,
-                       MM_ATTRS_FLAG_RW,
-                       (void *) 0,
-                       MM_ATTRS_VALID_TYPE_INT_RANGE,
-                       0,
-                       2
-               },
-               {
-                       (char *)"hdcp_port",
-                       MM_ATTRS_TYPE_INT,
-                       MM_ATTRS_FLAG_RW,
-                       (void *) 0,
-                       MM_ATTRS_VALID_TYPE_INT_RANGE,
-                       0,
-                       2147483647
-               },
-       };
-
-       num_of_attrs = ARRAY_SIZE(wfd_attrs);
-
-       base = (mmf_attrs_construct_info_t *)malloc(num_of_attrs * sizeof(mmf_attrs_construct_info_t));
-
-       if (!base) {
-               debug_error("Cannot create mmwfd attribute\n");
-               goto ERROR;
-       }
-
-       /* initialize values of attributes */
-       for (idx = 0; idx < num_of_attrs; idx++) {
-               base[idx].name = wfd_attrs[idx].name;
-               base[idx].value_type = wfd_attrs[idx].value_type;
-               base[idx].flags = wfd_attrs[idx].flags;
-               base[idx].default_value = wfd_attrs[idx].default_value;
-       }
-
-       attrs = mmf_attrs_new_from_data(
-                                       "mmwfd_attrs",
-                                       base,
-                                       num_of_attrs,
-                                       NULL,
-                                       NULL);
-
-       if (base) {
-               g_free(base);
-               base = NULL;
-       }
-
-       if (!attrs) {
-               debug_error("Cannot create mmwfd attribute\n");
-               goto ERROR;
-       }
-
-       /* set validity type and range */
-       for (idx = 0; idx < num_of_attrs; idx++) {
-               switch (wfd_attrs[idx].valid_type) {
-                       case MM_ATTRS_VALID_TYPE_INT_RANGE: {
-                                       mmf_attrs_set_valid_type(attrs, idx, MM_ATTRS_VALID_TYPE_INT_RANGE);
-                                       mmf_attrs_set_valid_range(attrs, idx,
-                                                                               wfd_attrs[idx].value_min,
-                                                                               wfd_attrs[idx].value_max,
-                                                                               (int)wfd_attrs[idx].default_value);
-                               }
-                               break;
-
-                       case MM_ATTRS_VALID_TYPE_INT_ARRAY:
-                       case MM_ATTRS_VALID_TYPE_DOUBLE_ARRAY:
-                       case MM_ATTRS_VALID_TYPE_DOUBLE_RANGE:
-                       default:
-                               break;
-               }
-       }
-
-       debug_fleave();
-
-       return attrs;
-
-ERROR:
-       _mmwfd_deconstruct_attribute(attrs);
-
-       return (MMHandleType)NULL;
-}
-
-void
-_mmwfd_deconstruct_attribute(MMHandleType handle)
-{
-       debug_fenter();
-
-       return_if_fail(handle);
-
-       if (handle)
-               mmf_attrs_free(handle);
-
-       debug_fleave();
-}
-
-int
-_mmwfd_get_attribute(MMHandleType handle,  char **err_attr_name, const char *attribute_name, va_list args_list)
-{
-       int result = MM_ERROR_NONE;
-       MMHandleType attrs = 0;
-
-       debug_fenter();
-
-       /* NOTE : Don't need to check err_attr_name because it can be set NULL */
-       /* if it's not want to know it. */
-       return_val_if_fail(attribute_name, MM_ERROR_COMMON_INVALID_ARGUMENT);
-       return_val_if_fail(handle, MM_ERROR_COMMON_INVALID_ARGUMENT);
-
-       attrs = handle;
-
-       return_val_if_fail(attrs, MM_ERROR_COMMON_INVALID_ARGUMENT);
-
-       result = mm_attrs_get_valist(attrs, err_attr_name, attribute_name, args_list);
-
-       if (result != MM_ERROR_NONE)
-               debug_error("failed to get %s attribute\n", attribute_name);
-
-       debug_fleave();
-
-       return result;
-}
-
-int
-_mmwfd_set_attribute(MMHandleType handle,  char **err_attr_name, const char *attribute_name, va_list args_list)
-{
-       int result = MM_ERROR_NONE;
-       MMHandleType attrs = 0;
-
-       debug_fenter();
-
-       /* NOTE : Don't need to check err_attr_name because it can be set NULL */
-       /* if it's not want to know it. */
-       return_val_if_fail(attribute_name, MM_ERROR_COMMON_INVALID_ARGUMENT);
-       return_val_if_fail(handle, MM_ERROR_COMMON_INVALID_ARGUMENT);
-
-       attrs = handle;
-
-       return_val_if_fail(attrs, MM_ERROR_COMMON_INVALID_ARGUMENT);
-
-       /* set attributes and commit them */
-       result = mm_attrs_set_valist(attrs, err_attr_name, attribute_name, args_list);
-
-       if (result != MM_ERROR_NONE) {
-               debug_error("failed to set %s attribute\n", attribute_name);
-               return result;
-       }
-
-       /*__mmwfd_apply_attribute(handle, attribute_name); */
-
-       debug_fleave();
-
-       return result;
-}
-
-/* Currently not used. */
-/*static gboolean
-__mmwfd_apply_attribute(MMHandleType handle, const char *attribute_name)
-{
-  MMHandleType attrs = 0;
-  mm_wfd_t* wfd = 0;
-
-  debug_fenter();
-
-  return_val_if_fail(handle, MM_ERROR_COMMON_INVALID_ARGUMENT);
-  return_val_if_fail(attribute_name, MM_ERROR_COMMON_INVALID_ARGUMENT);
-
-  attrs = handle;
-
-  return_val_if_fail(attrs, MM_ERROR_COMMON_INVALID_ARGUMENT);
-
-  wfd = (mm_wfd_t*)handle;
-
-  // TODO: This function is not useful at this moment
-
-  debug_fleave();
-
-  return TRUE;
-}*/
-
-int
-_mmwfd_get_attributes_info(MMHandleType handle,  const char *attribute_name, MMWfdAttrsInfo *dst_info)
-{
-       int result = MM_ERROR_NONE;
-       MMHandleType attrs = 0;
-       MMAttrsInfo src_info = {0, };
-
-       debug_fenter();
-
-       return_val_if_fail(attribute_name, MM_ERROR_COMMON_INVALID_ARGUMENT);
-       return_val_if_fail(dst_info, MM_ERROR_COMMON_INVALID_ARGUMENT);
-       return_val_if_fail(handle, MM_ERROR_COMMON_INVALID_ARGUMENT);
-
-       attrs = handle;
-
-       return_val_if_fail(attrs, MM_ERROR_COMMON_INVALID_ARGUMENT);
-
-       result = mm_attrs_get_info_by_name(attrs, attribute_name, &src_info);
-
-       if (result != MM_ERROR_NONE) {
-               debug_error("failed to get attribute info\n");
-               return result;
-       }
-
-       memset(dst_info, 0x00, sizeof(MMWfdAttrsInfo));
-
-       dst_info->type = src_info.type;
-       dst_info->flag = src_info.flag;
-       dst_info->validity_type = src_info.validity_type;
-
-       switch (src_info.validity_type) {
-               case MM_ATTRS_VALID_TYPE_INT_ARRAY:
-                       dst_info->int_array.array = src_info.int_array.array;
-                       dst_info->int_array.count = src_info.int_array.count;
-                       dst_info->int_array.d_val = src_info.int_array.dval;
-                       break;
-
-               case MM_ATTRS_VALID_TYPE_INT_RANGE:
-                       dst_info->int_range.min = src_info.int_range.min;
-                       dst_info->int_range.max = src_info.int_range.max;
-                       dst_info->int_range.d_val = src_info.int_range.dval;
-                       break;
-
-               case MM_ATTRS_VALID_TYPE_DOUBLE_ARRAY:
-                       dst_info->double_array.array = src_info.double_array.array;
-                       dst_info->double_array.count = src_info.double_array.count;
-                       dst_info->double_array.d_val = src_info.double_array.dval;
-                       break;
-
-               case MM_ATTRS_VALID_TYPE_DOUBLE_RANGE:
-                       dst_info->double_range.min = src_info.double_range.min;
-                       dst_info->double_range.max = src_info.double_range.max;
-                       dst_info->double_range.d_val = src_info.double_range.dval;
-                       break;
-
-               default:
-                       break;
-       }
-
-       debug_fleave();
-
-       return result;
-}
-
-
diff --git a/common/mm_wfd_sink_ini.c b/common/mm_wfd_sink_ini.c
deleted file mode 100755 (executable)
index 24b7de4..0000000
+++ /dev/null
@@ -1,374 +0,0 @@
-/*
- * libmm-wfd
- *
- * Copyright (c) 2011 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
- *
- * Contact: JongHyuk Choi <jhchoi.choi@samsung.com>, ByungWook Jang <bw.jang@samsung.com>,
- * Manoj Kumar K <manojkumar.k@samsung.com>, Hyunil Park <hyunil46.park@samsung.com>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-#include <glib.h>
-#include <glib/gstdio.h>
-#include <stdlib.h>
-#include <iniparser.h>
-#include <mm_error.h>
-#include "mm_wfd_sink_ini.h"
-#include "mm_wfd_sink_dlog.h"
-
-static gboolean loaded = FALSE;
-
-/* global variables here */
-#ifdef MM_WFD_SINK_DEFAULT_INI
-static gboolean        __generate_sink_default_ini(void);
-#endif
-
-static void __mm_wfd_sink_ini_check_status(void);
-
-/* macro */
-#define MM_WFD_SINK_INI_GET_STRING(x_dict, x_item, x_ini, x_default) \
-       do { \
-               gchar *str = NULL; \
-               gint length = 0; \
-               \
-               str = iniparser_getstring(x_dict, x_ini, (char *)x_default); \
-               if (str) { \
-                       length = strlen(str); \
-                       if ((length > 1) && (length < WFD_SINK_INI_MAX_STRLEN)) \
-                               strncpy(x_item, str, WFD_SINK_INI_MAX_STRLEN-1); \
-                       else \
-                               strncpy(x_item, x_default, WFD_SINK_INI_MAX_STRLEN-1); \
-               } else { \
-                       strncpy(x_item, x_default, WFD_SINK_INI_MAX_STRLEN-1); \
-               } \
-       } while (0);
-
-#ifdef MM_WFD_SINK_DEFAULT_INI
-static
-gboolean __generate_sink_default_ini(void)
-{
-       FILE *fp = NULL;
-       const gchar *default_ini = MM_WFD_SINK_DEFAULT_INI;
-
-
-       /* create new file */
-       fp = fopen(MM_WFD_SINK_INI_DEFAULT_PATH, "wt");
-
-       if (!fp) {
-               return FALSE;
-       }
-
-       /* writing default ini file */
-       if (strlen(default_ini) != fwrite(default_ini, 1, strlen(default_ini), fp)) {
-               fclose(fp);
-               return FALSE;
-       }
-
-       fclose(fp);
-       return TRUE;
-}
-#endif
-
-int
-mm_wfd_sink_ini_load(mm_wfd_sink_ini_t *ini)
-{
-       dictionary *dict = NULL;
-
-       wfd_sink_debug_fenter();
-
-
-       __mm_wfd_sink_ini_check_status();
-
-       /* first, try to load existing ini file */
-       dict = iniparser_load(MM_WFD_SINK_INI_DEFAULT_PATH);
-
-       /* if no file exists. create one with set of default values */
-       if (!dict) {
-#ifdef MM_WFD_SINK_DEFAULT_INI
-               wfd_sink_debug("No inifile found. create default ini file.\n");
-               if (FALSE == __generate_sink_default_ini()) {
-                       wfd_sink_error("Creating default ini file failed. Use default values.\n");
-               } else {
-                       /* load default ini */
-                       dict = iniparser_load(MM_WFD_SINK_INI_DEFAULT_PATH);
-               }
-#else
-               wfd_sink_error("No ini file found. \n");
-
-               return MM_ERROR_FILE_NOT_FOUND;
-#endif
-       }
-
-       /* get ini values */
-       memset(ini, 0, sizeof(mm_wfd_sink_ini_t));
-
-       if (dict) { /* if dict is available */
-               /* general */
-               MM_WFD_SINK_INI_GET_STRING(dict, ini->gst_param[0], "general:gstparam1", DEFAULT_GST_PARAM);
-               MM_WFD_SINK_INI_GET_STRING(dict, ini->gst_param[1], "general:gstparam2", DEFAULT_GST_PARAM);
-               MM_WFD_SINK_INI_GET_STRING(dict, ini->gst_param[2], "general:gstparam3", DEFAULT_GST_PARAM);
-               MM_WFD_SINK_INI_GET_STRING(dict, ini->gst_param[3], "general:gstparam4", DEFAULT_GST_PARAM);
-               MM_WFD_SINK_INI_GET_STRING(dict, ini->gst_param[4], "general:gstparam5", DEFAULT_GST_PARAM);
-               ini->generate_dot = iniparser_getboolean(dict, "general:generate dot", DEFAULT_GENERATE_DOT);
-               ini->enable_pad_probe = iniparser_getboolean(dict, "general:enable pad probe", DEFAULT_ENABLE_PAD_PROBE);
-               ini->state_change_timeout = iniparser_getint(dict, "general:state change timeout", DEFAULT_STATE_CHANGE_TIMEOUT);
-               ini->set_debug_property = iniparser_getboolean(dict, "general:set debug property", DEFAULT_SET_DEBUG_PROPERTY);
-               ini->enable_asm = iniparser_getboolean(dict, "general:enable asm", DEFAULT_ENABLE_ASM);
-               ini->jitter_buffer_latency = iniparser_getint(dict, "general:jitter buffer latency", DEFAULT_JITTER_BUFFER_LATENCY);
-               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_wfdsrc_pad_probe = iniparser_getboolean(dict, "general:enable wfdsrc pad probe", DEFAULT_ENABLE_WFDRTSPSRC_PAD_PROBE);
-
-
-               /* pipeline */
-               MM_WFD_SINK_INI_GET_STRING(dict, ini->name_of_source, "pipeline:wfdsrc element", DEFAULT_NAME_OF_SOURCE);
-               MM_WFD_SINK_INI_GET_STRING(dict, ini->name_of_tsdemux, "pipeline:tsdemux element", DEFAULT_NAME_OF_TSDEMUX);
-               MM_WFD_SINK_INI_GET_STRING(dict, ini->name_of_audio_hdcp, "pipeline:audio hdcp element", DEFAULT_NAME_OF_AUDIO_HDCP);
-               MM_WFD_SINK_INI_GET_STRING(dict, ini->name_of_aac_parser, "pipeline:aac parser element", DEFAULT_NAME_OF_AAC_PARSER);
-               MM_WFD_SINK_INI_GET_STRING(dict, ini->name_of_aac_decoder, "pipeline:aac decoder element", DEFAULT_NAME_OF_AAC_DECODER);
-               MM_WFD_SINK_INI_GET_STRING(dict, ini->name_of_ac3_parser, "pipeline:ac3 parser element", DEFAULT_NAME_OF_AC3_PARSER);
-               MM_WFD_SINK_INI_GET_STRING(dict, ini->name_of_ac3_decoder, "pipeline:ac3 decoder element", DEFAULT_NAME_OF_AC3_DECODER);
-               MM_WFD_SINK_INI_GET_STRING(dict, ini->name_of_lpcm_converter, "pipeline:lpcm converter element", DEFAULT_NAME_OF_LPCM_CONVERTER);
-               MM_WFD_SINK_INI_GET_STRING(dict, ini->name_of_lpcm_filter, "pipeline:lpcm filter element", DEFAULT_NAME_OF_LPCM_FILTER);
-               MM_WFD_SINK_INI_GET_STRING(dict, ini->name_of_audio_resampler, "pipeline:audio resampler element", DEFAULT_NAME_OF_AUDIO_RESAMPLER);
-               MM_WFD_SINK_INI_GET_STRING(dict, ini->name_of_audio_volume, "pipeline:audio volume element", DEFAULT_NAME_OF_AUDIO_VOLUME);
-               MM_WFD_SINK_INI_GET_STRING(dict, ini->name_of_audio_sink, "pipeline:audio sink element", DEFAULT_NAME_OF_AUDIO_SINK);
-               MM_WFD_SINK_INI_GET_STRING(dict, ini->name_of_video_hdcp, "pipeline:video hdcp element", DEFAULT_NAME_OF_VIDEO_HDCP);
-               MM_WFD_SINK_INI_GET_STRING(dict, ini->name_of_video_parser, "pipeline:video parser element", DEFAULT_NAME_OF_VIDEO_PARSER);
-               MM_WFD_SINK_INI_GET_STRING(dict, ini->name_of_video_capssetter, "pipeline:video capssetter element", DEFAULT_NAME_OF_VIDEO_CAPSSETTER);
-               MM_WFD_SINK_INI_GET_STRING(dict, ini->name_of_video_decoder, "pipeline:video decoder element", DEFAULT_NAME_OF_VIDEO_DECODER);
-               MM_WFD_SINK_INI_GET_STRING(dict, ini->name_of_video_converter, "pipeline:video converter element", DEFAULT_NAME_OF_VIDEO_CONVERTER);
-               MM_WFD_SINK_INI_GET_STRING(dict, ini->name_of_video_filter, "pipeline:video filter element", DEFAULT_NAME_OF_VIDEO_FILTER);
-               MM_WFD_SINK_INI_GET_STRING(dict, ini->name_of_video_sink, "pipeline:video sink element", DEFAULT_NAME_OF_VIDEO_SINK);
-               MM_WFD_SINK_INI_GET_STRING(dict, ini->name_of_video_evas_sink, "pipeline:video evas sink element", DEFAULT_NAME_OF_EVAS_VIDEO_SINK);
-
-               /* audio parameter*/
-               ini->audio_codec = iniparser_getint(dict, "audio param:audio codec", DEFAULT_AUDIO_CODEC);
-               ini->audio_latency = iniparser_getint(dict, "audio param:audio latency", DEFAULT_AUDIO_LATENCY);
-               ini->audio_channel = iniparser_getint(dict, "audio param:audio channels", DEFAULT_AUDIO_CHANNELS);
-               ini->audio_sampling_frequency = iniparser_getint(dict, "audio param:audio sampling frequency", DEFAULT_AUDIO_SAMP_FREQUENCY);
-
-               /* video parameter*/
-               ini->video_codec = iniparser_getint(dict, "video param:video codec", DEFAULT_VIDEO_CODEC);
-               ini->video_native_resolution = iniparser_getint(dict, "video param:video native resolution", DEFAULT_VIDEO_NATIVE_RESOLUTION);
-               ini->video_cea_support = iniparser_getint(dict, "video param:video cea support", DEFAULT_VIDEO_CEA_SUPPORT);
-               ini->video_vesa_support = iniparser_getint(dict, "video param:video vesa support", DEFAULT_VIDEO_VESA_SUPPORT);
-               ini->video_hh_support = iniparser_getint(dict, "video param:video hh support", DEFAULT_VIDEO_HH_SUPPORT);
-               ini->video_profile = iniparser_getint(dict, "video param:video profile", DEFAULT_VIDEO_PROFILE);
-               ini->video_level = iniparser_getint(dict, "video param:video level", DEFAULT_VIDEO_LEVEL);
-               ini->video_latency = iniparser_getint(dict, "video param:video latency", DEFAULT_VIDEO_LATENCY);
-               ini->video_vertical_resolution = iniparser_getint(dict, "video param:video vertical resolution", DEFAULT_VIDEO_VERTICAL_RESOLUTION);
-               ini->video_horizontal_resolution = iniparser_getint(dict, "video param:video horizontal resolution", DEFAULT_VIDEO_HORIZONTAL_RESOLUTION);
-               ini->video_minimum_slicing = iniparser_getint(dict, "video param:video minimum slicesize", DEFAULT_VIDEO_MIN_SLICESIZE);
-               ini->video_slice_enc_param = iniparser_getint(dict, "video param:video slice encoding params", DEFAULT_VIDEO_SLICE_ENC_PARAM);
-               ini->video_framerate_control_support = iniparser_getint(dict, "video param:video framerate control support", DEFAULT_VIDEO_FRAMERATE_CONTROL);
-
-               /* hdcp parameter*/
-               ini->hdcp_content_protection = iniparser_getint(dict, "hdcp param:hdcp content protection", DEFAULT_HDCP_CONTENT_PROTECTION);
-               ini->hdcp_port_no = iniparser_getint(dict, "hdcp param:hdcp port no", DEFAULT_HDCP_PORT_NO);
-       } else { /* if dict is not available just fill the structure with default value */
-               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);
-               strncpy(ini->gst_param[1], DEFAULT_GST_PARAM, WFD_SINK_INI_MAX_STRLEN - 1);
-               strncpy(ini->gst_param[2], DEFAULT_GST_PARAM, WFD_SINK_INI_MAX_STRLEN - 1);
-               strncpy(ini->gst_param[3], DEFAULT_GST_PARAM, WFD_SINK_INI_MAX_STRLEN - 1);
-               strncpy(ini->gst_param[4], DEFAULT_GST_PARAM, WFD_SINK_INI_MAX_STRLEN - 1);
-               ini->generate_dot =  DEFAULT_GENERATE_DOT;
-               ini->enable_pad_probe = DEFAULT_ENABLE_PAD_PROBE;
-               ini->state_change_timeout = DEFAULT_STATE_CHANGE_TIMEOUT;
-               ini->set_debug_property =  DEFAULT_SET_DEBUG_PROPERTY;
-               ini->enable_asm =  DEFAULT_ENABLE_ASM;
-               ini->jitter_buffer_latency = DEFAULT_JITTER_BUFFER_LATENCY;
-               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_wfdsrc_pad_probe = DEFAULT_ENABLE_WFDRTSPSRC_PAD_PROBE;
-
-               /* pipeline */
-               strncpy(ini->name_of_source, DEFAULT_NAME_OF_TSDEMUX, WFD_SINK_INI_MAX_STRLEN - 1);
-               strncpy(ini->name_of_tsdemux, DEFAULT_NAME_OF_TSDEMUX, WFD_SINK_INI_MAX_STRLEN - 1);
-               strncpy(ini->name_of_audio_hdcp, DEFAULT_NAME_OF_AUDIO_HDCP, WFD_SINK_INI_MAX_STRLEN - 1);
-               strncpy(ini->name_of_aac_parser, DEFAULT_NAME_OF_AAC_PARSER, WFD_SINK_INI_MAX_STRLEN - 1);
-               strncpy(ini->name_of_aac_decoder, DEFAULT_NAME_OF_AAC_DECODER, WFD_SINK_INI_MAX_STRLEN - 1);
-               strncpy(ini->name_of_ac3_parser, DEFAULT_NAME_OF_AC3_PARSER, WFD_SINK_INI_MAX_STRLEN - 1);
-               strncpy(ini->name_of_ac3_decoder, DEFAULT_NAME_OF_AC3_DECODER, WFD_SINK_INI_MAX_STRLEN - 1);
-               strncpy(ini->name_of_lpcm_converter, DEFAULT_NAME_OF_LPCM_CONVERTER, WFD_SINK_INI_MAX_STRLEN - 1);
-               strncpy(ini->name_of_lpcm_filter, DEFAULT_NAME_OF_LPCM_FILTER, WFD_SINK_INI_MAX_STRLEN - 1);
-               strncpy(ini->name_of_audio_resampler, DEFAULT_NAME_OF_AUDIO_RESAMPLER, WFD_SINK_INI_MAX_STRLEN - 1);
-               strncpy(ini->name_of_audio_volume, DEFAULT_NAME_OF_AUDIO_VOLUME, WFD_SINK_INI_MAX_STRLEN - 1);
-               strncpy(ini->name_of_audio_sink, DEFAULT_NAME_OF_AUDIO_SINK, WFD_SINK_INI_MAX_STRLEN - 1);
-               strncpy(ini->name_of_video_hdcp, DEFAULT_NAME_OF_VIDEO_HDCP, WFD_SINK_INI_MAX_STRLEN - 1);
-               strncpy(ini->name_of_video_parser, DEFAULT_NAME_OF_VIDEO_PARSER, WFD_SINK_INI_MAX_STRLEN - 1);
-               strncpy(ini->name_of_video_capssetter, DEFAULT_NAME_OF_VIDEO_CAPSSETTER, WFD_SINK_INI_MAX_STRLEN - 1);
-               strncpy(ini->name_of_video_decoder, DEFAULT_NAME_OF_VIDEO_DECODER, WFD_SINK_INI_MAX_STRLEN - 1);
-               strncpy(ini->name_of_video_converter, DEFAULT_NAME_OF_VIDEO_CONVERTER, WFD_SINK_INI_MAX_STRLEN - 1);
-               strncpy(ini->name_of_video_filter, DEFAULT_NAME_OF_VIDEO_FILTER, WFD_SINK_INI_MAX_STRLEN - 1);
-               strncpy(ini->name_of_video_sink, DEFAULT_NAME_OF_VIDEO_SINK, WFD_SINK_INI_MAX_STRLEN - 1);
-               strncpy(ini->name_of_video_evas_sink, DEFAULT_NAME_OF_EVAS_VIDEO_SINK, WFD_SINK_INI_MAX_STRLEN - 1);
-
-               /* audio parameter*/
-               ini->audio_codec = DEFAULT_AUDIO_CODEC;
-               ini->audio_latency = DEFAULT_AUDIO_LATENCY;
-               ini->audio_channel = DEFAULT_AUDIO_CHANNELS;
-               ini->audio_sampling_frequency = DEFAULT_AUDIO_SAMP_FREQUENCY;
-
-               /* video parameter*/
-               ini->video_codec = DEFAULT_VIDEO_CODEC;
-               ini->video_native_resolution = DEFAULT_VIDEO_NATIVE_RESOLUTION;
-               ini->video_cea_support = DEFAULT_VIDEO_CEA_SUPPORT;
-               ini->video_vesa_support = DEFAULT_VIDEO_VESA_SUPPORT;
-               ini->video_hh_support = DEFAULT_VIDEO_HH_SUPPORT;
-               ini->video_profile = DEFAULT_VIDEO_PROFILE;
-               ini->video_level = DEFAULT_VIDEO_LEVEL;
-               ini->video_latency = DEFAULT_VIDEO_LATENCY;
-               ini->video_vertical_resolution = DEFAULT_VIDEO_VERTICAL_RESOLUTION;
-               ini->video_horizontal_resolution = DEFAULT_VIDEO_HORIZONTAL_RESOLUTION;
-               ini->video_minimum_slicing = DEFAULT_VIDEO_MIN_SLICESIZE;
-               ini->video_slice_enc_param = DEFAULT_VIDEO_SLICE_ENC_PARAM;
-               ini->video_framerate_control_support = DEFAULT_VIDEO_FRAMERATE_CONTROL;
-
-               /* hdcp parameter*/
-               ini->hdcp_content_protection = DEFAULT_HDCP_CONTENT_PROTECTION;
-               ini->hdcp_port_no = DEFAULT_HDCP_PORT_NO;
-       }
-
-       /* free dict as we got our own structure */
-       iniparser_freedict(dict);
-
-
-       /* dump structure */
-       wfd_sink_debug("W-Fi Display Sink Initial Settings-----------------------------------\n");
-
-       /* general */
-       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) {
-               wfd_sink_debug("generate_dot is TRUE, dot file will be stored into /tmp/\n");
-               g_setenv("GST_DEBUG_DUMP_DOT_DIR", "/tmp/", FALSE);
-       }
-       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_wfdsrc_pad_probe : %d\n", ini->enable_wfdsrc_pad_probe);
-
-       /* pipeline */
-       wfd_sink_debug("name_of_source : %s\n", ini->name_of_source);
-       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);
-       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_capssetter : %s\n", ini->name_of_video_capssetter);
-       wfd_sink_debug("name_of_video_decoder : %s\n", ini->name_of_video_decoder);
-       wfd_sink_debug("name_of_video_converter : %s\n", ini->name_of_video_converter);
-       wfd_sink_debug("name_of_video_filter : %s\n", ini->name_of_video_filter);
-       wfd_sink_debug("name_of_video_sink : %s\n", ini->name_of_video_sink);
-       wfd_sink_debug("name_of_video_evas_sink : %s\n", ini->name_of_video_evas_sink);
-
-       /* audio parameter*/
-       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*/
-       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*/
-       wfd_sink_debug("hdcp_content_protection : %x\n", ini->hdcp_content_protection);
-       wfd_sink_debug("hdcp_port_no : %d\n", ini->hdcp_port_no);
-
-       wfd_sink_debug("---------------------------------------------------\n");
-
-       loaded = TRUE;
-
-       wfd_sink_debug_fleave();
-
-       return MM_ERROR_NONE;
-}
-
-
-static
-void __mm_wfd_sink_ini_check_status(void)
-{
-       struct stat ini_buff;
-
-       wfd_sink_debug_fenter();
-
-       if (g_stat(MM_WFD_SINK_INI_DEFAULT_PATH, &ini_buff) < 0) {
-               wfd_sink_error("failed to get mmfw_wfd_sink ini status\n");
-       } else {
-               if (ini_buff.st_size < 5) {
-                       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);
-               }
-       }
-
-       wfd_sink_debug_fleave();
-}
-
-int
-mm_wfd_sink_ini_unload(mm_wfd_sink_ini_t *ini)
-{
-       wfd_sink_debug_fenter();
-
-       loaded = FALSE;
-
-       wfd_sink_debug_fleave();
-
-       return MM_ERROR_NONE;
-}
diff --git a/config/Makefile.am b/config/Makefile.am
deleted file mode 100755 (executable)
index eb1a3b9..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-installconfiguredir=$(_sysconfdir)/multimedia
-installconfigure_DATA=mmfw_wfd_sink.ini
diff --git a/config/Makefile.in b/config/Makefile.in
deleted file mode 100755 (executable)
index b3eb062..0000000
+++ /dev/null
@@ -1,386 +0,0 @@
-# Makefile.in generated by automake 1.10.2 from Makefile.am.
-# @configure_input@
-
-# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-# 2003, 2004, 2005, 2006, 2007, 2008  Free Software Foundation, Inc.
-# This Makefile.in is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
-# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
-# PARTICULAR PURPOSE.
-
-@SET_MAKE@
-
-VPATH = @srcdir@
-pkgdatadir = $(datadir)/@PACKAGE@
-pkglibdir = $(libdir)/@PACKAGE@
-pkgincludedir = $(includedir)/@PACKAGE@
-am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
-install_sh_DATA = $(install_sh) -c -m 644
-install_sh_PROGRAM = $(install_sh) -c
-install_sh_SCRIPT = $(install_sh) -c
-INSTALL_HEADER = $(INSTALL_DATA)
-transform = $(program_transform_name)
-NORMAL_INSTALL = :
-PRE_INSTALL = :
-POST_INSTALL = :
-NORMAL_UNINSTALL = :
-PRE_UNINSTALL = :
-POST_UNINSTALL = :
-build_triplet = @build@
-host_triplet = @host@
-subdir = config
-DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
-ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
-am__aclocal_m4_deps = $(top_srcdir)/configure.ac
-am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
-       $(ACLOCAL_M4)
-mkinstalldirs = $(install_sh) -d
-CONFIG_HEADER = $(top_builddir)/config.h
-CONFIG_CLEAN_FILES =
-SOURCES =
-DIST_SOURCES =
-am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
-am__vpath_adj = case $$p in \
-    $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
-    *) f=$$p;; \
-  esac;
-am__strip_dir = `echo $$p | sed -e 's|^.*/||'`;
-am__installdirs = "$(DESTDIR)$(installconfiguredir)"
-installconfigureDATA_INSTALL = $(INSTALL_DATA)
-DATA = $(installconfigure_DATA)
-DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
-ACLOCAL = @ACLOCAL@
-AMTAR = @AMTAR@
-APPFWK_CFLAGS = @APPFWK_CFLAGS@
-APPFWK_LIBS = @APPFWK_LIBS@
-AR = @AR@
-AUDIOSESSIONMGR_CFLAGS = @AUDIOSESSIONMGR_CFLAGS@
-AUDIOSESSIONMGR_LIBS = @AUDIOSESSIONMGR_LIBS@
-AUTOCONF = @AUTOCONF@
-AUTOHEADER = @AUTOHEADER@
-AUTOMAKE = @AUTOMAKE@
-AWK = @AWK@
-CC = @CC@
-CCDEPMODE = @CCDEPMODE@
-CFLAGS = @CFLAGS@
-CPP = @CPP@
-CPPFLAGS = @CPPFLAGS@
-CYGPATH_W = @CYGPATH_W@
-DEFS = @DEFS@
-DEPDIR = @DEPDIR@
-DSYMUTIL = @DSYMUTIL@
-DUMPBIN = @DUMPBIN@
-ECHO_C = @ECHO_C@
-ECHO_N = @ECHO_N@
-ECHO_T = @ECHO_T@
-EGREP = @EGREP@
-ELEMENTARY_CFLAGS = @ELEMENTARY_CFLAGS@
-ELEMENTARY_LIBS = @ELEMENTARY_LIBS@
-EXEEXT = @EXEEXT@
-FGREP = @FGREP@
-GLIB_CFLAGS = @GLIB_CFLAGS@
-GLIB_LIBS = @GLIB_LIBS@
-GREP = @GREP@
-GST_APP_CFLAGS = @GST_APP_CFLAGS@
-GST_APP_LIBS = @GST_APP_LIBS@
-GST_CFLAGS = @GST_CFLAGS@
-GST_INTERFACE_CFLAGS = @GST_INTERFACE_CFLAGS@
-GST_INTERFACE_LIBS = @GST_INTERFACE_LIBS@
-GST_LIBS = @GST_LIBS@
-GST_PLUGIN_BASE_CFLAGS = @GST_PLUGIN_BASE_CFLAGS@
-GST_PLUGIN_BASE_LIBS = @GST_PLUGIN_BASE_LIBS@
-INIPARSER_CFLAGS = @INIPARSER_CFLAGS@
-INIPARSER_LIBS = @INIPARSER_LIBS@
-INSTALL = @INSTALL@
-INSTALL_DATA = @INSTALL_DATA@
-INSTALL_PROGRAM = @INSTALL_PROGRAM@
-INSTALL_SCRIPT = @INSTALL_SCRIPT@
-INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
-LD = @LD@
-LDFLAGS = @LDFLAGS@
-LIBOBJS = @LIBOBJS@
-LIBS = @LIBS@
-LIBTOOL = @LIBTOOL@
-LIPO = @LIPO@
-LN_S = @LN_S@
-LTLIBOBJS = @LTLIBOBJS@
-MAKEINFO = @MAKEINFO@
-MKDIR_P = @MKDIR_P@
-MMCOMMON_CFLAGS = @MMCOMMON_CFLAGS@
-MMCOMMON_LIBS = @MMCOMMON_LIBS@
-MMSESSION_CFLAGS = @MMSESSION_CFLAGS@
-MMSESSION_LIBS = @MMSESSION_LIBS@
-MMSOUND_CFLAGS = @MMSOUND_CFLAGS@
-MMSOUND_LIBS = @MMSOUND_LIBS@
-MMTA_CFLAGS = @MMTA_CFLAGS@
-MMTA_LIBS = @MMTA_LIBS@
-MMUTIL_CFLAGS = @MMUTIL_CFLAGS@
-MMUTIL_LIBS = @MMUTIL_LIBS@
-NM = @NM@
-NMEDIT = @NMEDIT@
-OBJEXT = @OBJEXT@
-OTOOL = @OTOOL@
-OTOOL64 = @OTOOL64@
-PACKAGE = @PACKAGE@
-PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
-PACKAGE_NAME = @PACKAGE_NAME@
-PACKAGE_STRING = @PACKAGE_STRING@
-PACKAGE_TARNAME = @PACKAGE_TARNAME@
-PACKAGE_VERSION = @PACKAGE_VERSION@
-PATH_SEPARATOR = @PATH_SEPARATOR@
-PKG_CONFIG = @PKG_CONFIG@
-RANLIB = @RANLIB@
-SAVSIMGP_CFLAGS = @SAVSIMGP_CFLAGS@
-SAVSIMGP_LIBS = @SAVSIMGP_LIBS@
-SED = @SED@
-SET_MAKE = @SET_MAKE@
-SHELL = @SHELL@
-STRIP = @STRIP@
-VERSION = @VERSION@
-abs_builddir = @abs_builddir@
-abs_srcdir = @abs_srcdir@
-abs_top_builddir = @abs_top_builddir@
-abs_top_srcdir = @abs_top_srcdir@
-ac_ct_CC = @ac_ct_CC@
-ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
-am__include = @am__include@
-am__leading_dot = @am__leading_dot@
-am__quote = @am__quote@
-am__tar = @am__tar@
-am__untar = @am__untar@
-bindir = @bindir@
-build = @build@
-build_alias = @build_alias@
-build_cpu = @build_cpu@
-build_os = @build_os@
-build_vendor = @build_vendor@
-builddir = @builddir@
-datadir = @datadir@
-datarootdir = @datarootdir@
-docdir = @docdir@
-dvidir = @dvidir@
-exec_prefix = @exec_prefix@
-host = @host@
-host_alias = @host_alias@
-host_cpu = @host_cpu@
-host_os = @host_os@
-host_vendor = @host_vendor@
-htmldir = @htmldir@
-includedir = @includedir@
-infodir = @infodir@
-install_sh = @install_sh@
-libdir = @libdir@
-libexecdir = @libexecdir@
-localedir = @localedir@
-localstatedir = @localstatedir@
-lt_ECHO = @lt_ECHO@
-mandir = @mandir@
-mkdir_p = @mkdir_p@
-oldincludedir = @oldincludedir@
-pdfdir = @pdfdir@
-prefix = @prefix@
-program_transform_name = @program_transform_name@
-psdir = @psdir@
-sbindir = @sbindir@
-sharedstatedir = @sharedstatedir@
-srcdir = @srcdir@
-sysconfdir = @sysconfdir@
-target_alias = @target_alias@
-top_builddir = @top_builddir@
-top_srcdir = @top_srcdir@
-installconfiguredir = /opt/etc
-installconfigure_DATA = mmfw_player.ini
-all: all-am
-
-.SUFFIXES:
-$(srcdir)/Makefile.in:  $(srcdir)/Makefile.am  $(am__configure_deps)
-       @for dep in $?; do \
-         case '$(am__configure_deps)' in \
-           *$$dep*) \
-             ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
-               && { if test -f $@; then exit 0; else break; fi; }; \
-             exit 1;; \
-         esac; \
-       done; \
-       echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign  config/Makefile'; \
-       cd $(top_srcdir) && \
-         $(AUTOMAKE) --foreign  config/Makefile
-.PRECIOUS: Makefile
-Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
-       @case '$?' in \
-         *config.status*) \
-           cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
-         *) \
-           echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
-           cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
-       esac;
-
-$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
-       cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
-
-$(top_srcdir)/configure:  $(am__configure_deps)
-       cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
-$(ACLOCAL_M4):  $(am__aclocal_m4_deps)
-       cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
-
-mostlyclean-libtool:
-       -rm -f *.lo
-
-clean-libtool:
-       -rm -rf .libs _libs
-install-installconfigureDATA: $(installconfigure_DATA)
-       @$(NORMAL_INSTALL)
-       test -z "$(installconfiguredir)" || $(MKDIR_P) "$(DESTDIR)$(installconfiguredir)"
-       @list='$(installconfigure_DATA)'; for p in $$list; do \
-         if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
-         f=$(am__strip_dir) \
-         echo " $(installconfigureDATA_INSTALL) '$$d$$p' '$(DESTDIR)$(installconfiguredir)/$$f'"; \
-         $(installconfigureDATA_INSTALL) "$$d$$p" "$(DESTDIR)$(installconfiguredir)/$$f"; \
-       done
-
-uninstall-installconfigureDATA:
-       @$(NORMAL_UNINSTALL)
-       @list='$(installconfigure_DATA)'; for p in $$list; do \
-         f=$(am__strip_dir) \
-         echo " rm -f '$(DESTDIR)$(installconfiguredir)/$$f'"; \
-         rm -f "$(DESTDIR)$(installconfiguredir)/$$f"; \
-       done
-tags: TAGS
-TAGS:
-
-ctags: CTAGS
-CTAGS:
-
-
-distdir: $(DISTFILES)
-       @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
-       topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
-       list='$(DISTFILES)'; \
-         dist_files=`for file in $$list; do echo $$file; done | \
-         sed -e "s|^$$srcdirstrip/||;t" \
-             -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
-       case $$dist_files in \
-         */*) $(MKDIR_P) `echo "$$dist_files" | \
-                          sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
-                          sort -u` ;; \
-       esac; \
-       for file in $$dist_files; do \
-         if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
-         if test -d $$d/$$file; then \
-           dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
-           if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
-             cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
-           fi; \
-           cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
-         else \
-           test -f $(distdir)/$$file \
-           || cp -p $$d/$$file $(distdir)/$$file \
-           || exit 1; \
-         fi; \
-       done
-check-am: all-am
-check: check-am
-all-am: Makefile $(DATA)
-installdirs:
-       for dir in "$(DESTDIR)$(installconfiguredir)"; do \
-         test -z "$$dir" || $(MKDIR_P) "$$dir"; \
-       done
-install: install-am
-install-exec: install-exec-am
-install-data: install-data-am
-uninstall: uninstall-am
-
-install-am: all-am
-       @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
-
-installcheck: installcheck-am
-install-strip:
-       $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
-         install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
-         `test -z '$(STRIP)' || \
-           echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
-mostlyclean-generic:
-
-clean-generic:
-
-distclean-generic:
-       -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
-
-maintainer-clean-generic:
-       @echo "This command is intended for maintainers to use"
-       @echo "it deletes files that may require special tools to rebuild."
-clean: clean-am
-
-clean-am: clean-generic clean-libtool mostlyclean-am
-
-distclean: distclean-am
-       -rm -f Makefile
-distclean-am: clean-am distclean-generic
-
-dvi: dvi-am
-
-dvi-am:
-
-html: html-am
-
-info: info-am
-
-info-am:
-
-install-data-am: install-installconfigureDATA
-
-install-dvi: install-dvi-am
-
-install-exec-am:
-
-install-html: install-html-am
-
-install-info: install-info-am
-
-install-man:
-
-install-pdf: install-pdf-am
-
-install-ps: install-ps-am
-
-installcheck-am:
-
-maintainer-clean: maintainer-clean-am
-       -rm -f Makefile
-maintainer-clean-am: distclean-am maintainer-clean-generic
-
-mostlyclean: mostlyclean-am
-
-mostlyclean-am: mostlyclean-generic mostlyclean-libtool
-
-pdf: pdf-am
-
-pdf-am:
-
-ps: ps-am
-
-ps-am:
-
-uninstall-am: uninstall-installconfigureDATA
-
-.MAKE: install-am install-strip
-
-.PHONY: all all-am check check-am clean clean-generic clean-libtool \
-       distclean distclean-generic distclean-libtool distdir dvi \
-       dvi-am html html-am info info-am install install-am \
-       install-data install-data-am install-dvi install-dvi-am \
-       install-exec install-exec-am install-html install-html-am \
-       install-info install-info-am install-installconfigureDATA \
-       install-man install-pdf install-pdf-am install-ps \
-       install-ps-am install-strip installcheck installcheck-am \
-       installdirs maintainer-clean maintainer-clean-generic \
-       mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \
-       ps ps-am uninstall uninstall-am uninstall-installconfigureDATA
-
-# Tell versions [3.59,3.63) of GNU make to not export all variables.
-# Otherwise a system limit (for SysV at least) may be exceeded.
-.NOEXPORT:
index 7893e7bcaeb0277ef32997af54e2a63a8dea9d31..8488f12af801e4ee541e7f7d802d0af9fcd77438 100755 (executable)
@@ -3,7 +3,7 @@
 
 AC_PREREQ(2.61)
 AC_INIT([libmm-wfd],[0.0.1])
-AC_CONFIG_SRCDIR([sink/mm_wfd_sink_priv.c])
+AC_CONFIG_SRCDIR([src/mm_wfd_sink_priv.c])
 AC_CONFIG_HEADER([config.h])
 AM_INIT_AUTOMAKE([-Wall -Werror foreign])
 
@@ -107,8 +107,7 @@ AC_ARG_ENABLE(sdk, AC_HELP_STRING([--enable-sdk], [sdk build]),
 AM_CONDITIONAL([IS_SDK], [test "x$IS_SDK" = "xyes"])
 
 AC_CONFIG_FILES([Makefile
-                common/Makefile
-                sink/Makefile
-                mm-wfd.pc
+               src/Makefile
+               mm-wfd.pc
 ])
 AC_OUTPUT
index c1cfb18857fce03d3245f920d31e78b5051723b5..8f0a6baba97ef3125cb4c985ba3a2b79e18727d8 100755 (executable)
@@ -1,6 +1,6 @@
 Name:       libmm-wfd
 Summary:    Multimedia Framework Wifi-Display Library
-Version:    0.2.195
+Version:    0.2.196
 Release:    0
 Group:      System/Libraries
 License:    Apache-2.0
@@ -89,6 +89,11 @@ rm -rf %{buildroot}
 %defattr(-,root,root,-)
 %{_libdir}/*.so
 %{_includedir}/mmf/mm_wfd_sink.h
+%{_includedir}/mmf/mm_wfd_sink_priv.h
+%{_includedir}/mmf/mm_wfd_sink_dlog.h
+%{_includedir}/mmf/mm_wfd_sink_util.h
+%{_includedir}/mmf/mm_wfd_sink_ini.h
+%{_includedir}/mmf/mm_wfd_sink_attrs.h
 %{_libdir}/pkgconfig/*
 
 #%files factory
diff --git a/sink/Makefile.am b/sink/Makefile.am
deleted file mode 100755 (executable)
index 2ee962d..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-lib_LTLIBRARIES = libmmfwfdsink.la
-
-includelibmmfwfdsinkdir = $(includedir)/mmf
-
-includelibmmfwfdsink_HEADERS = include/mm_wfd_sink.h
-
-libmmfwfdsink_la_SOURCES = mm_wfd_sink_util.c \
-                               mm_wfd_sink.c \
-                               mm_wfd_sink_manager.c \
-                               mm_wfd_sink_priv.c \
-                               mm_wfd_sink_wayland.c
-
-
-libmmfwfdsink_la_CFLAGS =  -I$(srcdir)/include \
-                       $(MMCOMMON_CFLAGS) \
-                       $(GST_CFLAGS) \
-                       $(EVAS_CFLAGS) \
-                       $(ELEMENTARY_CFLAGS) \
-                       $(GST_PLUGINS_BASE_CFLAGS) \
-                       $(GST_VIDEO_CFLAGS) \
-                       $(MM_WFD_COMMON_CFLAGS) \
-                       $(AUDIOSESSIONMGR_CFLAGS) \
-                       $(TZPLATFORM_CONFIG_CFLAGS) \
-                       -I$(top_builddir)/common/include
-
-
-libmmfwfdsink_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
-
-noinst_HEADERS = include/mm_wfd_sink_priv.h \
-                       include/mm_wfd_sink_util.h \
-                       include/mm_wfd_sink_manager.h \
-                       include/mm_wfd_sink_wayland.h
-
-libmmfwfdsink_la_LIBADD = $(GST_LIBS) \
-                       $(GST_PLUGINS_BASE_LIBS) \
-                       $(GST_BASE_LIBS) \
-                       $(ELEMENTARY_LIBS) \
-                       $(EVAS_LIBS) \
-                       $(top_builddir)/common/libwfdcommon.la \
-                       $(MMCOMMON_LIBS) \
-                       $(MM_WFD_COMMON_LIBS) \
-                       $(AUDIOSESSIONMGR_LIBS) \
-                       $(TZPLATFORM_CONFIG_LIBS) \
-                       $(GST_VIDEO_LIBS)
-
-
-libmmfwfdsink_la_CFLAGS += $(MMLOG_CFLAGS) -DMMF_LOG_OWNER=0x02000000 -DMMF_DEBUG_PREFIX=\"MMF-WFD-SINK\"
-libmmfwfdsink_la_LIBADD += $(MMLOG_LIBS)
diff --git a/sink/include/mm_wfd_sink.h b/sink/include/mm_wfd_sink.h
deleted file mode 100755 (executable)
index 620324f..0000000
+++ /dev/null
@@ -1,484 +0,0 @@
-/*
- * libmm-wfd
- *
- * Copyright (c) 2011 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
- *
- * Contact: JongHyuk Choi <jhchoi.choi@samsung.com>, ByungWook Jang <bw.jang@samsung.com>,
- * Maksym Ukhanov <m.ukhanov@samsung.com>, Hyunjun Ko <zzoon.ko@samsung.com>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-#ifndef _MM_WFD_SINK_H_
-#define _MM_WFD_SINK_H_
-
-#include <string.h>
-#include <glib.h>
-#include <mm_message.h>
-#include <mm_error.h>
-#include <mm_types.h>
-
-/**
- *  * Enumerations of wifi-display sink state.
- *   */
-typedef enum {
-       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;
-
-/* audio codec : AAC, AC3, LPCM  */
-typedef enum {
-       MM_WFD_SINK_AUDIO_CODEC_NONE,
-       MM_WFD_SINK_AUDIO_CODEC_AAC = 0x0F,
-       MM_WFD_SINK_AUDIO_CODEC_AC3 = 0x81,
-       MM_WFD_SINK_AUDIO_CODEC_LPCM = 0x83
-} MMWFDSinkAudioCodec;
-
-/* video codec : H264  */
-typedef enum {
-       MM_WFD_SINK_VIDEO_CODEC_NONE,
-       MM_WFD_SINK_VIDEO_CODEC_H264 = 0x1b
-} MMWFDSinkVideoCodec;
-
-typedef void(*MMWFDMessageCallback)(int error_type, MMWFDSinkStateType state_type, void *user_data);
-
-/**
- * This function creates a wi-fi display sink object. \n
- * The attributes of wi-fi display sink are created to get/set some values with application. \n
- * And, mutex, gstreamer and other resources are initialized at this time. \n
- * If wi-fi display sink is created, he state will become MM_WFD_SINK_STATE_NULL.. \n
- *
- * @param      wfd_sink                [out]   Handle of wi-fi display sink
- *
- * @return     This function returns zero on success, or negative value with error code. \n
- *                     Please refer 'mm_error.h' to know it in detail.
- * @pre                None
- * @post               MM_WFD_SINK_STATE_NULL
- * @see                mm_wfd_sink_destroy
- * @remark     You can create multiple handles on a context at the same time. \n
- *                     However, wi-fi display sink cannot guarantee proper operation because of limitation of resources, \n
- *                     such as audio device or display device.
- *
- * @par Example
- * @code
-if (mm_wfd_sink_create(&g_wfd_sink) != MM_ERROR_NONE)
-{
-       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);
- * @endcode
- */
-int mm_wfd_sink_create(MMHandleType *wfd_sink);
-
-/**
- * This function trys to make gstreamer pipeline. \n
- * If wi-fi display sink is realized, the state will become MM_WFD_SINK_STATE_READY.. \n
- *
- * @param      wfd_sink                [out]   Handle of wi-fi display sink
- *
- * @return     This function returns zero on success, or negative value with error code. \n
- *                     Please refer 'mm_error.h' to know it in detail.
- * @pre                MM_WFD_SINK_STATE_NULL
- * @post               MM_WFD_SINK_STATE_PREPARED
- * @see                mm_wfd_sink_unprepare
- * @remark     None
- * @par Example
- * @code
-if (mm_wfd_sink_prepare(&g_wfd_sink) != MM_ERROR_NONE)
-{
-       wfd_sink_error("failed to realize wi-fi display sink\n");
-}
- * @endcode
- */
-int mm_wfd_sink_prepare(MMHandleType wfd_sink);
-
-/**
- * This function connect wi-fi display source using uri. \n
- * audio type(AC3 AAC, LPCM) is decided at this time. \n
- *
- * @param      wfd_sink                [in]    Handle of wi-fi display sink
- * @param      uri                     [in]    URI of wi-fi displaysource to be connected
- *
- * @return     This function returns zero on success, or negative value with error code.
- *
- * @pre                wi-fi display sink state should be MM_WFD_SINK_STATE_PREPARED
- * @post               wi-fi display sink state will be MM_WFD_SINK_STATE_CONNECTED with no preroll.
- * @remark     None
- * @par Example
- * @code
-if (mm_wfd_sink_connect(g_wfd_sink, g_uri) != MM_ERROR_NONE)
-{
-       wfd_sink_error("failed to connect to wi-fi display source\n");
-}
- * @endcode
- */
-int mm_wfd_sink_connect(MMHandleType wfd_sink, const char *uri);
-
-/**
- * This function is to start playing. \n
- * Data from wi-fi display source will be received. \n
- *
- * @param      wfd_sink                [in]    Handle of wi-fi display sink
- *
- * @return     This function returns zero on success, or negative value with error code.
- * @remark
- *
- * @pre                wi-fi display sink state may be MM_WFD_SINK_STATE_CONNECTED.
- * @post               wi-fi display sink state will be MM_WFD_SINK_STATE_PLAYING.
- * @see                mm_wfd_sink_disconnect
- * @remark     None
- * @par Example
- * @code
-if (mm_wfd_sink_start(g_wfd_sink) != MM_ERROR_NONE)
-{
-       wfd_sink_error("failed to start wi-fi display sink\n");
-}
- * @endcode
- */
-int mm_wfd_sink_start(MMHandleType wfd_sink);
-
-/**
- * This function is to pause playing. \n
- * The wi-fi display sink pause the current stream being received form wi-fi display source. \n
- *
- * @param      wfd_sink                [in]    Handle of wi-fi display sink
- *
- * @return     This function returns zero on success, or negative value with error code.
- * @remark
- *
- * @pre                wi-fi display sink state should be MM_WFD_SINK_STATE_PLAYING.
- * @post               wi-fi display sink state will be MM_WFD_SINK_STATE_PAUSED.
- * @see                mm_wfd_sink_pause
- * @remark     None
- * @par Example
- * @code
-if (mm_wfd_sink_pause(g_wfd_sink) != MM_ERROR_NONE)
-{
-       wfd_sink_error("failed to pause wi-fi display sink\n");
-}
- * @endcode
- */
-int mm_wfd_sink_pause(MMHandleType wfd_sink);
-
-/**
- * This function is to resume playing. \n
- * Data from wi-fi display source will be received. \n
- *
- * @param      wfd_sink                [in]    Handle of wi-fi display sink
- *
- * @return     This function returns zero  on success, or negative value with error code.
- * @remark
- *
- * @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_disconnect
- * @remark     None
- * @par Example
- * @code
-if (mm_wfd_sink_start(g_wfd_sink) != MM_ERROR_NONE)
-{
-       wfd_sink_error("failed to resume wi-fi display sink\n");
-}
- * @endcode
- */
-int mm_wfd_sink_resume(MMHandleType wfd_sink);
-
-/**
- * This function is to stop playing wi-fi display. \n
- *
- * @param      wfd_sink                [in]    Handle of wi-fi display sink
- *
- * @return     This function returns zero on success, or negative value with error code.
- *
- * @pre                wi-fi display sink state may be MM_WFD_SINK_STATE_PLAYING.
- * @post               wi-fi display sink state will be MM_WFD_SINK_STATE_DISCONNECTED.
- * @see                mm_wfd_sink_start
- * @remark     None
- * @par Example
- * @code
-if (mm_wfd_sink_disconnect(g_wfd_sink) != MM_ERROR_NONE)
-{
-       wfd_sink_error("failed to stop wi-fi display sink\n");
-}
- * @endcode
- */
-int mm_wfd_sink_disconnect(MMHandleType wfd_sink);
-
-/**
- * This function trys to destroy gstreamer pipeline. \n
- *
- * @param      wfd_sink                [out]   Handle of wi-fi display sink
- *
- * @return     This function returns zero on success, or negative value with error code. \n
- *                     Please refer 'mm_error.h' to know it in detail.
- * @pre                wi-fi display sink state may be MM_WFD_SINK_STATE_PREPARED or MM_WFD_SINK_STATE_DISCONNECTED.
- *                     But, it can be called in any state.
- * @post               MM_WFD_SINK_STATE_NULL
- * @see                mm_wfd_sink_prepare
- * @remark     None
- * @par Example
- * @code
-if (mm_wfd_sink_unprepare(&g_wfd_sink) != MM_ERROR_NONE)
-{
-       wfd_sink_error("failed to unprepare wi-fi display sink\n");
-}
- * @endcode
- */
-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
- * And, wi-fi display sink handle will also be destroyed. \n
- *
- * @param      wfd_sink                [in]    Handle of wi-fi display sink
- *
- * @return     This function returns zero on success, or negative value with error code.
- * @pre                wi-fi display state may be MM_WFD_SINK_STATE_NULL. \n
- *                     But, it can be called in any state.
- * @post               Because handle is released, there is no any state.
- * @see                mm_wfd_sink_create
- * @remark     This method can be called with a valid wi-fi display sink handle from any state to \n
- *                     completely shutdown the wi-fi display sink operation.
- *
- * @par Example
- * @code
-if (mm_wfd_sink_destroy(g_wfd_sink) != MM_ERROR_NONE)
-{
-       wfd_sink_error("failed to destroy wi-fi display sink\n");
-}
- * @endcode
- */
-int mm_wfd_sink_destroy(MMHandleType wfd_sink);
-
-/**
- * This function sets callback function for receiving messages from wi-fi display sink. \n
- * So, player can notify warning, error and normal cases to application. \n
- *
- * @param      wfd_sink                [in]    Handle of wi-fi display sink
- * @param      callback        [in]    Message callback function.
- * @param      user_param      [in]    User parameter which is passed to callback function.
- *
- * @return     This function returns zero on success, or negative value with error code.
- * @see                MMWFDMessageCallback
- * @remark     None
- * @par Example
- * @code
-
-int msg_callback(int error_type, MMWFDSinkStateType state_type, void *user_data)
-{
-       switch (state_type)
-       {
-               case MM_WFD_SINK_STATE_NULL:
-                       //do something
-                       break;
-
-               case MM_WFD_SINK_STATE_PREPARED:
-                       //do something
-                       break;
-
-               case MM_WFD_SINK_STATE_CONNECTED:
-                       //do something
-                       break;
-
-               case MM_WFD_SINK_STATE_PLAYING:
-                       //do something
-                       break;
-
-               case MM_WFD_SINK_STATE_PAUSED:
-                       //do something
-                       break;
-
-               case MM_WFD_SINK_DISCONNECTED:
-                       //do something
-                       break;
-
-               default:
-                       break;
-       }
-       return TRUE;
-}
-
-mm_wfd_sink_set_message_callback(g_wfd_sink, msg_callback, (void*)g_wfd_sink);
- * @endcode
- */
-int mm_wfd_sink_set_message_callback(MMHandleType wfd_sink, MMWFDMessageCallback callback, void *user_param);
-
-int mm_wfd_sink_set_attribute(MMHandleType wfd_sink,  char **err_attr_name, const char *first_attribute_name, ...);
-
-/**
- * This function get resources \n
- *
- * @param      wfd_sink                [in]    Handle of wi-fi display sink
- *
- * @return     This function returns zero on success, or negative value with error code.
- * @pre                wi-fi display state should be MM_WFD_SINK_STATE_READY or MM_WFD_SINK_STATE_PREPARED. \n
- * @post               N/A
- * @remark     resources are released when mm_wfd_sink_destory is called
- *
- * @par Example
- * @code
-if (mm_wfd_sink_get_resource(g_wfd_sink) != MM_ERROR_NONE)
-{
-       wfd_sink_error("failed to get resources for wi-fi display sink\n");
-}
- * @endcode
- */
-int mm_wfd_sink_get_resource(MMHandleType wfd_sink);
-
-/**
- * This function sets the display surface type for wi-fi display sink\n
- *
- * @param      wfd_sink                [in]    Handle of wi-fi display sink
- * @param      display_surface_type            [in]    Display surface type
- *
- * @return     This function returns zero on success, or negative value with error code.
- * @pre                wi-fi display state should be MM_WFD_SINK_STATE_NULL. \n
- *
- * @par Example
- * @code
-if (mm_wfd_sink_set_display_surface_type(g_wfd_sink, g_display_surface_type) != MM_ERROR_NONE)
-{
-       wfd_sink_error("failed to set display surface type for wi-fi display sink\n");
-}
- * @endcode
- */
-int mm_wfd_sink_set_display_surface_type(MMHandleType wfd_sink, gint display_surface_type);
-
-/**
- * This function sets the display overlay for wi-fi display sink\n
- *
- * @param      wfd_sink                [in]    Handle of wi-fi display sink
- * @param      display_overlay         [in]    Display overlay
- *
- * @return     This function returns zero on success, or negative value with error code.
- * @pre                wi-fi display state should be MM_WFD_SINK_STATE_NULL. \n
- *
- * @par Example
- * @code
-if (mm_wfd_sink_set_display_overlay(g_wfd_sink, g_display_overlay) != MM_ERROR_NONE)
-{
-       wfd_sink_error("failed to set display overlay for wi-fi display sink\n");
-}
- * @endcode
- */
-int mm_wfd_sink_set_display_overlay(MMHandleType wfd_sink, void *display_overlay);
-
-/**
- * This function sets the display method for wi-fi display sink\n
- *
- * @param      wfd_sink                [in]    Handle of wi-fi display sink
- * @param      display_method          [in]    Display method
- *
- * @return     This function returns zero on success, or negative value with error code.
- * @pre                wi-fi display state should be MM_WFD_SINK_STATE_NULL. \n
- *
- * @par Example
- * @code
-if (mm_wfd_sink_set_display_method(g_wfd_sink, g_display_method) != MM_ERROR_NONE)
-{
-       wfd_sink_error("failed to set display method for wi-fi display sink\n");
-}
- * @endcode
- */
-int mm_wfd_sink_set_display_method(MMHandleType wfd_sink, gint display_method);
-
-/**
- * This function sets the display visible for wi-fi display sink\n
- *
- * @param      wfd_sink                [in]    Handle of wi-fi display sink
- * @param      display_visible         [in]    Display visible
- *
- * @return     This function returns zero on success, or negative value with error code.
- * @pre                wi-fi display state should be MM_WFD_SINK_STATE_NULL. \n
- *
- * @par Example
- * @code
-if (mm_wfd_sink_set_display_visible(g_wfd_sink, g_display_visible) != MM_ERROR_NONE)
-{
-       wfd_sink_error("failed to set display visible for wi-fi display sink\n");
-}
- * @endcode
- */
-int mm_wfd_sink_set_display_visible(MMHandleType wfd_sink, gint display_visible);
-
-/**
- * This function gets the width and height of video which is played by wi-fi display sink\n
- *
- * @param      wfd_sink                [in]    Handle of wi-fi display sink
- * @param      width           [in]    Width of video
- * @param      height          [in]    Height of video
- *
- * @return     This function returns zero on success, or negative value with error code.
- * @pre                wi-fi display state should be MM_WFD_SINK_STATE_CONNECTED or MM_WFD_SINK_STATE_PLAYING. \n
- *
- * @par Example
- * @code
-gint g_width=0, g_height=0;
-
-if (mm_wfd_sink_get_video_resolution(g_wfd_sink, &g_width, &g_height) != MM_ERROR_NONE)
-{
-       wfd_sink_error("failed to get video resolution.\n");
-}
- * @endcode
- */
-int mm_wfd_sink_get_video_resolution(MMHandleType wfd_sink, gint *width, gint *height);
-
-/**
- * This function gets the width and height of video which is played by wi-fi display sink\n
- *
- * @param      wfd_sink                [in]    Handle of wi-fi display sink
- * @param      framerate               [in]    Framerate of video
- *
- * @return     This function returns zero on success, or negative value with error code.
- * @pre                wi-fi display state should be MM_WFD_SINK_STATE_CONNECTED or MM_WFD_SINK_STATE_PLAYING. \n
- *
- * @par Example
- * @code
-gint g_framerate=0;
-
-if (mm_wfd_sink_get_video_framerate(g_wfd_sink, &g_framerate) != MM_ERROR_NONE)
-{
-       wfd_sink_error("failed to get video framerate.\n");
-}
- * @endcode
- */
-int mm_wfd_sink_get_video_framerate(MMHandleType wfd_sink,  gint *framerate);
-
-/**
- * This function sets the resolutions for wi-fi display sink\n
- *
- * @param      wfd_sink                [in]    Handle of wi-fi display sink
- * @param      resolution              [in]    Resolutions for wi-fi display sink
- *
- * @return     This function returns zero on success, or negative value with error code.
- * @pre                wi-fi display state should be MM_WFD_SINK_STATE_NULL. \n
- *
- */
-int mm_wfd_sink_set_resolution(MMHandleType wfd_sink,  gint resolution);
-
-int mm_wfd_sink_get_negotiated_video_codec(MMHandleType wfd_sink,  gint *codec);
-int mm_wfd_sink_get_negotiated_video_resolution(MMHandleType wfd_sink,  gint *width, gint *height);
-int mm_wfd_sink_get_negotiated_video_frame_rate(MMHandleType wfd_sink,  gint *frame_rate);
-int mm_wfd_sink_get_negotiated_audio_codec(MMHandleType wfd_sink,  gint *codec);
-int mm_wfd_sink_get_negotiated_audio_channel(MMHandleType wfd_sink,  gint *channel);
-int mm_wfd_sink_get_negotiated_audio_sample_rate(MMHandleType wfd_sink,  gint *sample_rate);
-int mm_wfd_sink_get_negotiated_audio_bitwidth(MMHandleType wfd_sink,  gint *bitwidth);
-#endif
diff --git a/sink/include/mm_wfd_sink_manager.h b/sink/include/mm_wfd_sink_manager.h
deleted file mode 100755 (executable)
index 47309e3..0000000
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * libmm-wfd
- *
- * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
- *
- * Contact: JongHyuk Choi <jhchoi.choi@samsung.com>, YeJin Cho <cho.yejin@samsung.com>,
- * Seungbae Shin <seungbae.shin@samsung.com>, YoungHwan An <younghwan_.an@samsung.com>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-#ifndef __MM_WFD_SINK_MANAGER_H__
-#define __MM_WFD_SINK_MANAGER_H__
-
-/*=======================================================================================
-| INCLUDE FILES                                                                                |
-========================================================================================*/
-#include "mm_wfd_sink_priv.h"
-#include "mm_wfd_sink_util.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#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 {\
-               if (wfd_sink->manager_thread_exit == FALSE) {\
-                       wfd_sink_debug("manager thread is waiting for command signal");\
-                       wfd_sink->waiting_cmd = TRUE; \
-                       g_cond_wait(&((wfd_sink)->manager_thread_cond), &((wfd_sink)->manager_thread_mutex)); \
-                       wfd_sink->waiting_cmd = FALSE; \
-               } else {\
-                       wfd_sink_debug("manager thread is stopped, don't need to wait for command signal");\
-               }\
-       } while (0);
-
-#define WFD_SINK_MANAGER_APPEND_CMD(wfd_sink, cmd) \
-       do {\
-               WFD_SINK_MANAGER_LOCK(wfd_sink);\
-               if (cmd == WFD_SINK_MANAGER_CMD_EXIT) {\
-                       g_list_free(wfd_sink->manager_thread_cmd);\
-                       wfd_sink->manager_thread_cmd = NULL;\
-                       wfd_sink->manager_thread_exit = TRUE;\
-               }\
-               wfd_sink->manager_thread_cmd = g_list_append(wfd_sink->manager_thread_cmd, GINT_TO_POINTER(cmd)); \
-               WFD_SINK_MANAGER_UNLOCK(wfd_sink);\
-       } while (0);
-
-#define WFD_SINK_MANAGER_SIGNAL_CMD(wfd_sink) \
-       do {\
-               WFD_SINK_MANAGER_LOCK(wfd_sink);\
-               if (wfd_sink->waiting_cmd) {\
-                       if (wfd_sink->manager_thread_cmd) {\
-                               wfd_sink_debug("send command signal to manager thread");\
-                               g_cond_signal(&((wfd_sink)->manager_thread_cond));\
-                       }\
-               }\
-               WFD_SINK_MANAGER_UNLOCK(wfd_sink);\
-       } while (0);
-
-/**
- * This function is to initialize manager
- *
- * @param[in]  handle          Handle of wfd_sink.
- * @return     This function returns zero on success, or negative value with errors.
- * @remarks
- * @see
- *
- */
-int _mm_wfd_sink_init_manager(mm_wfd_sink_t *wfd_sink);
-/**
- * This function is to release manager
- *
- * @param[in]  handle          Handle of wfd_sink.
- * @return     This function returns zero on success, or negative value with errors.
- * @remarks
- * @see
- *
- */
-int _mm_wfd_sink_release_manager(mm_wfd_sink_t *wfd_sink);
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/sink/include/mm_wfd_sink_priv.h b/sink/include/mm_wfd_sink_priv.h
deleted file mode 100755 (executable)
index 7d55a9a..0000000
+++ /dev/null
@@ -1,248 +0,0 @@
-/*
- * libmm-wfd
- *
- * Copyright (c) 2011 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
- *
- * Contact: JongHyuk Choi <jhchoi.choi@samsung.com>, ByungWook Jang <bw.jang@samsung.com>,
- * Maksym Ukhanov <m.ukhanov@samsung.com>, Hyunjun Ko <zzoon.ko@samsung.com>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-#ifndef _MM_WFD_SINK_PRIV_H_
-#define _MM_WFD_SINK_PRIV_H_
-
-#include <string.h>
-#include <stdlib.h>
-#include <glib.h>
-#include <gst/gst.h>
-#include <mm_types.h>
-#include <mm_attrs.h>
-#include <mm_message.h>
-#include <mm_error.h>
-#include <mm_types.h>
-#include <mm_wfd_sink_ini.h>
-#include <mm_wfd_attrs.h>
-
-#include "mm_wfd_sink.h"
-
-/* main pipeline's element id */
-enum WFDSinkMainElementID {
-       WFD_SINK_M_PIPE = 0, /* NOTE : WFD_SINK_M_PIPE should be zero */
-       WFD_SINK_M_SRC,
-       WFD_SINK_M_DEPAY,
-       WFD_SINK_M_DEMUX,
-       WFD_SINK_M_NUM
-};
-
-/* audio decodebin's element id */
-enum WFDSinkAudioDecodeBinElementID {
-       WFD_SINK_A_D_BIN = 0, /* NOTE : WFD_SINK_A_D_BIN should be zero */
-       WFD_SINK_A_D_QUEUE,
-       WFD_SINK_A_D_HDCP,
-       WFD_SINK_A_D_AAC_PARSE,
-       WFD_SINK_A_D_AAC_DEC,
-       WFD_SINK_A_D_AC3_PARSE,
-       WFD_SINK_A_D_AC3_DEC,
-       WFD_SINK_A_D_LPCM_CONVERTER,
-       WFD_SINK_A_D_LPCM_FILTER,
-       WFD_SINK_A_D_NUM
-};
-
-/* audio sinkbin's element id */
-enum WFDSinkAudioSinkBinElementID {
-       WFD_SINK_A_S_BIN = 0, /* NOTE : WFD_SINK_A_S_BIN should be zero */
-       WFD_SINK_A_S_RESAMPLER,
-       WFD_SINK_A_S_VOLUME,
-       WFD_SINK_A_S_SINK,
-       WFD_SINK_A_S_NUM
-};
-
-/* video decodebin's element id */
-enum WFDSinkVideoDecodeBinElementID {
-       WFD_SINK_V_D_BIN = 0, /* NOTE : WFD_SINK_V_D_BIN should be zero */
-       WFD_SINK_V_D_QUEUE,
-       WFD_SINK_V_D_HDCP,
-       WFD_SINK_V_D_PARSE,
-       WFD_SINK_V_D_CAPSSETTER,
-       WFD_SINK_V_D_DEC,
-       WFD_SINK_V_D_NUM
-};
-
-/* video sinkbin's element id */
-enum WFDSinkVideoSinkBinElementID {
-       WFD_SINK_V_S_BIN = 0, /* NOTE : WFD_SINK_V_S_BIN should be zero */
-       WFD_SINK_V_S_CONVERT,
-       WFD_SINK_V_S_FILTER,
-       WFD_SINK_V_S_SINK,
-       WFD_SINK_V_S_NUM
-};
-
-/**
- *  * Enumerations of wifi-display command.
- *   */
-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_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_PAUSE,       /**< command for pausing wifi-display sink  */
-       MM_WFD_SINK_COMMAND_RESUME,      /**< command for resuming 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;
-
-/**
- *  * Enumerations of thread command.
- *   */
-typedef enum {
-       WFD_SINK_MANAGER_CMD_NONE = 0,
-       WFD_SINK_MANAGER_CMD_LINK_A_DECODEBIN,
-       WFD_SINK_MANAGER_CMD_LINK_V_DECODEBIN,
-       WFD_SINK_MANAGER_CMD_PREPARE_A_PIPELINE,
-       WFD_SINK_MANAGER_CMD_PREPARE_V_PIPELINE,
-       WFD_SINK_MANAGER_CMD_EXIT,
-} WFDSinkManagerCMDType;
-
-/**
- *  * Enumerations of resolution.
- *   */
-typedef enum {
-       MM_WFD_SINK_RESOLUTION_UNKNOWN = 0,
-       MM_WFD_SINK_RESOLUTION_1920x1080_P30 = (1 << 0),  /**< W-1920, H-1080, 30 fps*/
-       MM_WFD_SINK_RESOLUTION_1280x720_P30 = (1 << 1),   /**< W-1280, H-720, 30 fps*/
-       MM_WFD_SINK_RESOLUTION_960x540_P30 = (1 << 2),    /**< W-960, H-540, 30 fps*/
-       MM_WFD_SINK_RESOLUTION_864x480_P30 = (1 << 3),    /**< W-864, H-480, 30 fps*/
-       MM_WFD_SINK_RESOLUTION_720x480_P60 = (1 << 4),    /**< W-720, H-480, 30 fps*/
-       MM_WFD_SINK_RESOLUTION_640x480_P60 = (1 << 5),    /**< W-640, H-480, 60 fps*/
-       MM_WFD_SINK_RESOLUTION_640x360_P30 = (1 << 6),    /**< W-640, H-360, 30 fps*/
-       MM_WFD_SINK_RESOLUTION_MAX = 128,
-} MMWFDSinkResolution;
-
-typedef struct {
-       gint codec;
-       gint width;
-       gint height;
-       gint frame_rate;
-} MMWFDSinkVideoStreamInfo;
-
-typedef struct {
-       gint codec;
-       gint channels;
-       gint sample_rate;
-       gint bitwidth;
-} MMWFDSinkAudioStreamInfo;
-
-typedef struct {
-       MMWFDSinkAudioStreamInfo audio_stream_info;
-       MMWFDSinkVideoStreamInfo video_stream_info;
-} MMWFDSinkStreamInfo;
-
-
-typedef struct {
-       gint id;
-       GstElement *gst;
-} MMWFDSinkGstElement;
-
-typedef struct {
-       MMWFDSinkGstElement     *mainbin;
-       MMWFDSinkGstElement     *a_decodebin;
-       MMWFDSinkGstElement     *v_decodebin;
-       MMWFDSinkGstElement     *a_sinkbin;
-       MMWFDSinkGstElement     *v_sinkbin;
-} MMWFDSinkGstPipelineInfo;
-
-typedef struct {
-       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)
-
-typedef struct {
-       /* gstreamer pipeline */
-       MMWFDSinkGstPipelineInfo *pipeline;
-       gboolean audio_decodebin_is_linked;
-       gboolean video_decodebin_is_linked;
-
-       /* 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;
-
-       /* state */
-       MMWFDSinkState state;
-
-       /* initialize values */
-       mm_wfd_sink_ini_t ini;
-
-       /* command */
-       MMWFDSinkCommandType cmd;
-       GMutex cmd_lock;
-       gboolean waiting_cmd;
-
-       /* stream information */
-       MMWFDSinkStreamInfo stream_info;
-
-       /* Message handling */
-       MMWFDMessageCallback msg_cb;
-       void *msg_user_data;
-
-       /* video resolution for negotiation */
-       MMWFDSinkResolution supportive_resolution;
-
-       GThread         *manager_thread;
-       GMutex manager_thread_mutex;
-       GCond manager_thread_cond;
-       GList *manager_thread_cmd;
-       gboolean manager_thread_exit;
-} mm_wfd_sink_t;
-
-
-int _mm_wfd_sink_create(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_pause(mm_wfd_sink_t *wfd_sink);
-int _mm_wfd_sink_resume(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);
-int _mm_wfd_sink_set_resolution(mm_wfd_sink_t *wfd_sink, MMWFDSinkResolution resolution);
-
-int __mm_wfd_sink_link_audio_decodebin(mm_wfd_sink_t *wfd_sink);
-int __mm_wfd_sink_link_video_decodebin(mm_wfd_sink_t *wfd_sink);
-int __mm_wfd_sink_prepare_video_pipeline(mm_wfd_sink_t *wfd_sink);
-int __mm_wfd_sink_prepare_audio_pipeline(mm_wfd_sink_t *wfd_sink);
-
-const gchar *_mm_wfds_sink_get_state_name(MMWFDSinkStateType state);
-
-#endif
-
diff --git a/sink/include/mm_wfd_sink_util.h b/sink/include/mm_wfd_sink_util.h
deleted file mode 100755 (executable)
index 870982a..0000000
+++ /dev/null
@@ -1,130 +0,0 @@
-/*
- * libmm-wfd
- *
- * Copyright (c) 2011 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
- *
- * Contact: JongHyuk Choi <jhchoi.choi@samsung.com>, ByungWook Jang <bw.jang@samsung.com>,
- * Maksym Ukhanov <m.ukhanov@samsung.com>, Hyunjun Ko <zzoon.ko@samsung.com>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-#ifndef _MM_WFD_SINK_UTIL_H_
-#define _MM_WFD_SINK_UTIL_H_
-
-#include <glib.h>
-#include <gst/gst.h>
-#include <mm_message.h>
-#include <mm_error.h>
-#include <mm_types.h>
-#include "mm_wfd_sink_dlog.h"
-
-#define MMWFDSINK_FREEIF(x) \
-       do      {\
-               if ((x)) \
-                       g_free((gpointer)(x)); \
-               (x) = NULL;\
-       } while (0);
-
-/* lock for commnad */
-#define MMWFDSINK_CMD_LOCK(x_wfd) \
-       if (x_wfd) \
-               g_mutex_lock(&(((mm_wfd_sink_t *)x_wfd)->cmd_lock));
-
-#define MMWFDSINK_CMD_UNLOCK(x_wfd) \
-       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) \
-       do      { \
-               if (x_name && (strlen(x_factory) > 1)) {\
-                       x_bin[x_id].id = x_id;\
-                       x_bin[x_id].gst = gst_element_factory_make(x_factory, x_name);\
-                       if (! x_bin[x_id].gst)  {\
-                               wfd_sink_error("failed to create %s \n", x_factory);\
-                               goto CREATE_ERROR;\
-                       }\
-                       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 MMWFDSINK_GENERATE_DOT_IF_ENABLED(x_wfd_sink, x_name) \
-       if (x_wfd_sink->ini.generate_dot) { \
-               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); \
-       }
-
-/* 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
-#define MMWFDSINK_PENDING_STATE(x_wfd_sink) ((mm_wfd_sink_t *)x_wfd_sink)->state.pending_state
-#define MMWFDSINK_STATE_GET_NAME(x_state) _mm_wfds_sink_get_state_name(x_state)
-
-#define MMWFDSINK_PRINT_STATE(x_wfd_sink) \
-       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)));
-
-#define MMWFDSINK_CHECK_STATE(x_wfd_sink, x_cmd) \
-       switch (__mm_wfd_sink_check_state((mm_wfd_sink_t *)x_wfd_sink, x_cmd)) \
-       { \
-       case MM_ERROR_NONE: \
-               break;\
-       case MM_ERROR_WFD_NO_OP: \
-               return MM_ERROR_NONE; \
-               break; \
-       default: \
-               return MM_ERROR_WFD_INVALID_STATE; \
-               break; \
-       }
-
-
-/* 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) {  \
-               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
-mm_wfd_sink_util_add_pad_probe_for_data_dump(GstElement *element, const gchar *pad_name);
-
-#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); \
-       }
-
-#endif
diff --git a/sink/include/mm_wfd_sink_wayland.h b/sink/include/mm_wfd_sink_wayland.h
deleted file mode 100755 (executable)
index d3e6da6..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
-* 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_WLCLIENT_H__
-#define __MM_WFD_SINK_WLCLIENT_H__
-#include <stdio.h>
-#include <tbm_bufmgr.h>
-#include <tizen-extension-client-protocol.h>
-#include <wayland-client.h>
-#include <mm_types.h>
-#include <mm_debug.h>
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-
-typedef struct
-{
-       struct wl_display *display;
-       struct wl_registry *registry;
-       struct tizen_surface *tz_surface;
-       struct tizen_resource *tz_resource;
-} wl_client;
-
-int mm_wfd_sink_wlclient_create (wl_client ** wlclient);
-int mm_wfd_sink_wlclient_get_wl_window_wl_surface_id (wl_client * wlclient, struct wl_surface *surface, struct wl_display *display);
-void mm_wfd_sink_wlclient_finalize (wl_client * wlclient);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif                          /* __MM_WFD_SINK_WLCLIENT_H__ */
diff --git a/sink/mm_wfd_sink.c b/sink/mm_wfd_sink.c
deleted file mode 100755 (executable)
index fd0d335..0000000
+++ /dev/null
@@ -1,450 +0,0 @@
-/*
- * libmm-wfd
- *
- * Copyright (c) 2011 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
- *
- * Contact: JongHyuk Choi <jhchoi.choi@samsung.com>, ByungWook Jang <bw.jang@samsung.com>,
- * Maksym Ukhanov <m.ukhanov@samsung.com>, Hyunjun Ko <zzoon.ko@samsung.com>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-#include <gst/gst.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;
-
-       wfd_sink_debug_fenter();
-
-       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) {
-               wfd_sink_error("fail to create wi-fi display sink handle. ret[%d]", result);
-               *wfd_sink = (MMHandleType)NULL;
-               return result;
-       }
-
-       /* init wfd lock */
-       g_mutex_init(&new_wfd_sink->cmd_lock);
-
-       *wfd_sink = (MMHandleType)new_wfd_sink;
-
-       wfd_sink_debug_fleave();
-
-       return result;
-
-}
-
-int mm_wfd_sink_prepare(MMHandleType wfd_sink)
-{
-       int result = MM_ERROR_NONE;
-
-       wfd_sink_return_val_if_fail(wfd_sink, MM_ERROR_WFD_NOT_INITIALIZED);
-
-       MMWFDSINK_CMD_LOCK(wfd_sink);
-       result = _mm_wfd_sink_prepare((mm_wfd_sink_t *)wfd_sink);
-       MMWFDSINK_CMD_UNLOCK(wfd_sink);
-
-       return result;
-}
-
-int mm_wfd_sink_connect(MMHandleType wfd_sink, const char *uri)
-{
-       int result = MM_ERROR_NONE;
-
-       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);
-       MMWFDSINK_CMD_UNLOCK(wfd_sink);
-
-       return result;
-}
-
-int mm_wfd_sink_start(MMHandleType wfd_sink)
-{
-       int result = MM_ERROR_NONE;
-
-       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);
-       MMWFDSINK_CMD_UNLOCK(wfd_sink);
-
-       return result;
-}
-
-int mm_wfd_sink_pause(MMHandleType wfd_sink)
-{
-       int result = MM_ERROR_NONE;
-
-       wfd_sink_return_val_if_fail(wfd_sink, MM_ERROR_WFD_NOT_INITIALIZED);
-
-       MMWFDSINK_CMD_LOCK(wfd_sink);
-       result = _mm_wfd_sink_pause((mm_wfd_sink_t *)wfd_sink);
-       MMWFDSINK_CMD_UNLOCK(wfd_sink);
-
-       return result;
-}
-
-int mm_wfd_sink_resume(MMHandleType wfd_sink)
-{
-       int result = MM_ERROR_NONE;
-
-       wfd_sink_return_val_if_fail(wfd_sink, MM_ERROR_WFD_NOT_INITIALIZED);
-
-       MMWFDSINK_CMD_LOCK(wfd_sink);
-       result = _mm_wfd_sink_resume((mm_wfd_sink_t *)wfd_sink);
-       MMWFDSINK_CMD_UNLOCK(wfd_sink);
-
-       return result;
-}
-
-int mm_wfd_sink_disconnect(MMHandleType wfd_sink)
-{
-       int result = MM_ERROR_NONE;
-
-       wfd_sink_return_val_if_fail(wfd_sink, MM_ERROR_WFD_NOT_INITIALIZED);
-
-       MMWFDSINK_CMD_LOCK(wfd_sink);
-       result = _mm_wfd_sink_disconnect((mm_wfd_sink_t *)wfd_sink);
-       MMWFDSINK_CMD_UNLOCK(wfd_sink);
-
-       return result;
-}
-
-int mm_wfd_sink_unprepare(MMHandleType wfd_sink)
-{
-       int result = MM_ERROR_NONE;
-
-       wfd_sink_return_val_if_fail(wfd_sink, MM_ERROR_WFD_NOT_INITIALIZED);
-
-       MMWFDSINK_CMD_LOCK(wfd_sink);
-       result = _mm_wfd_sink_unprepare((mm_wfd_sink_t *)wfd_sink);
-       MMWFDSINK_CMD_UNLOCK(wfd_sink);
-
-       return result;
-}
-
-int mm_wfd_sink_destroy(MMHandleType wfd_sink)
-{
-       int result = MM_ERROR_NONE;
-       mm_wfd_sink_t *sink_handle = NULL;
-
-       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);
-
-       g_mutex_clear(&(((mm_wfd_sink_t *)wfd_sink)->cmd_lock));
-
-       sink_handle = (mm_wfd_sink_t *)wfd_sink;
-       MMWFDSINK_FREEIF(sink_handle);
-
-       return result;
-}
-
-int mm_wfd_sink_set_message_callback(MMHandleType wfd_sink, MMWFDMessageCallback callback, void *user_data)
-{
-       int result = MM_ERROR_NONE;
-
-       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);
-       MMWFDSINK_CMD_UNLOCK(wfd_sink);
-
-       return result;
-}
-
-int mm_wfd_sink_set_attribute(MMHandleType wfd_sink,  char **err_attr_name, const char *first_attribute_name, ...)
-{
-       int result = MM_ERROR_NONE;
-       va_list var_args;
-
-       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);
-       result = _mmwfd_set_attribute(MMWFDSINK_GET_ATTRS(wfd_sink), err_attr_name, first_attribute_name, var_args);
-       va_end(var_args);
-       MMWFDSINK_CMD_UNLOCK(wfd_sink);
-
-       return result;
-}
-
-int mm_wfd_sink_get_video_resolution(MMHandleType wfd_sink, gint *width, gint *height)
-{
-       mm_wfd_sink_t *wfd = (mm_wfd_sink_t *)wfd_sink;
-
-       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;
-
-       return MM_ERROR_NONE;
-}
-
-int mm_wfd_sink_get_video_framerate(MMHandleType wfd_sink, gint *frame_rate)
-{
-       mm_wfd_sink_t *wfd = (mm_wfd_sink_t *)wfd_sink;
-
-       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;
-
-       return MM_ERROR_NONE;
-}
-
-int mm_wfd_sink_set_resolution(MMHandleType wfd_sink,  gint resolution)
-{
-       int result = MM_ERROR_NONE;
-
-       wfd_sink_return_val_if_fail(wfd_sink, MM_ERROR_WFD_NOT_INITIALIZED);
-       MMWFDSINK_CMD_LOCK(wfd_sink);
-       result = _mm_wfd_sink_set_resolution((mm_wfd_sink_t *)wfd_sink, resolution);
-       MMWFDSINK_CMD_UNLOCK(wfd_sink);
-
-       return result;
-}
-
-int mm_wfd_sink_get_negotiated_video_codec(MMHandleType wfd_sink,  gint *codec)
-{
-       int result = MM_ERROR_NONE;
-       mm_wfd_sink_t *wfd = (mm_wfd_sink_t *)wfd_sink;
-       MMWFDSinkStateType cur_state = MM_WFD_SINK_STATE_NONE;
-
-       wfd_sink_return_val_if_fail(wfd, MM_ERROR_WFD_NOT_INITIALIZED);
-       wfd_sink_return_val_if_fail(codec, MM_ERROR_WFD_INVALID_ARGUMENT);
-
-       MMWFDSINK_CMD_LOCK(wfd);
-
-       MMWFDSINK_PRINT_STATE(wfd);
-       cur_state = MMWFDSINK_CURRENT_STATE(wfd);
-       if (cur_state != MM_WFD_SINK_STATE_CONNECTED &&
-               cur_state != MM_WFD_SINK_STATE_PLAYING &&
-               cur_state != MM_WFD_SINK_STATE_PAUSED) {
-
-               wfd_sink_error("This function must be called after MM_WFD_SINK_STATE_CONNECTED");
-               result = MM_ERROR_WFD_INVALID_STATE;
-       } else {
-               *codec = wfd->stream_info.video_stream_info.codec;
-       }
-
-       MMWFDSINK_CMD_UNLOCK(wfd);
-
-       wfd_sink_debug_fleave();
-
-       return result;
-}
-
-int mm_wfd_sink_get_negotiated_video_resolution(MMHandleType wfd_sink,  gint *width, gint *height)
-{
-       int result = MM_ERROR_NONE;
-       mm_wfd_sink_t *wfd = (mm_wfd_sink_t *)wfd_sink;
-       MMWFDSinkStateType cur_state = MM_WFD_SINK_STATE_NONE;
-
-       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);
-
-       MMWFDSINK_CMD_LOCK(wfd);
-
-       MMWFDSINK_PRINT_STATE(wfd);
-       cur_state = MMWFDSINK_CURRENT_STATE(wfd);
-       if (cur_state != MM_WFD_SINK_STATE_CONNECTED &&
-               cur_state != MM_WFD_SINK_STATE_PLAYING &&
-               cur_state != MM_WFD_SINK_STATE_PAUSED) {
-
-               wfd_sink_error("This function must be called after MM_WFD_SINK_STATE_CONNECTED");
-               result = MM_ERROR_WFD_INVALID_STATE;
-       } else {
-               *width = wfd->stream_info.video_stream_info.width;
-               *height = wfd->stream_info.video_stream_info.height;
-       }
-
-       MMWFDSINK_CMD_UNLOCK(wfd);
-
-       wfd_sink_debug_fleave();
-
-       return result;
-}
-
-int mm_wfd_sink_get_negotiated_video_frame_rate(MMHandleType wfd_sink,  gint *frame_rate)
-{
-       int result = MM_ERROR_NONE;
-       mm_wfd_sink_t *wfd = (mm_wfd_sink_t *)wfd_sink;
-       MMWFDSinkStateType cur_state = MM_WFD_SINK_STATE_NONE;
-
-       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);
-
-       MMWFDSINK_CMD_LOCK(wfd);
-
-       MMWFDSINK_PRINT_STATE(wfd);
-       cur_state = MMWFDSINK_CURRENT_STATE(wfd);
-       if (cur_state != MM_WFD_SINK_STATE_CONNECTED &&
-               cur_state != MM_WFD_SINK_STATE_PLAYING &&
-               cur_state != MM_WFD_SINK_STATE_PAUSED) {
-
-               wfd_sink_error("This function must be called after MM_WFD_SINK_STATE_CONNECTED");
-               result = MM_ERROR_WFD_INVALID_STATE;
-       } else {
-               *frame_rate = wfd->stream_info.video_stream_info.frame_rate;
-       }
-
-       MMWFDSINK_CMD_UNLOCK(wfd);
-
-       wfd_sink_debug_fleave();
-
-       return result;
-}
-
-int mm_wfd_sink_get_negotiated_audio_codec(MMHandleType wfd_sink,  gint *codec)
-{
-       int result = MM_ERROR_NONE;
-       mm_wfd_sink_t *wfd = (mm_wfd_sink_t *)wfd_sink;
-       MMWFDSinkStateType cur_state = MM_WFD_SINK_STATE_NONE;
-
-       wfd_sink_return_val_if_fail(wfd, MM_ERROR_WFD_NOT_INITIALIZED);
-       wfd_sink_return_val_if_fail(codec, MM_ERROR_WFD_INVALID_ARGUMENT);
-
-       MMWFDSINK_CMD_LOCK(wfd);
-
-       MMWFDSINK_PRINT_STATE(wfd);
-       cur_state = MMWFDSINK_CURRENT_STATE(wfd);
-       if (cur_state != MM_WFD_SINK_STATE_CONNECTED &&
-               cur_state != MM_WFD_SINK_STATE_PLAYING &&
-               cur_state != MM_WFD_SINK_STATE_PAUSED) {
-
-               wfd_sink_error("This function must be called after MM_WFD_SINK_STATE_CONNECTED");
-               result = MM_ERROR_WFD_INVALID_STATE;
-       } else {
-               *codec = wfd->stream_info.audio_stream_info.codec;
-       }
-
-       MMWFDSINK_CMD_UNLOCK(wfd);
-
-       wfd_sink_debug_fleave();
-
-       return result;
-}
-
-int mm_wfd_sink_get_negotiated_audio_channel(MMHandleType wfd_sink,  gint *channel)
-{
-       int result = MM_ERROR_NONE;
-       mm_wfd_sink_t *wfd = (mm_wfd_sink_t *)wfd_sink;
-       MMWFDSinkStateType cur_state = MM_WFD_SINK_STATE_NONE;
-
-       wfd_sink_return_val_if_fail(wfd, MM_ERROR_WFD_NOT_INITIALIZED);
-       wfd_sink_return_val_if_fail(channel, MM_ERROR_WFD_INVALID_ARGUMENT);
-
-       MMWFDSINK_CMD_LOCK(wfd);
-
-       MMWFDSINK_PRINT_STATE(wfd);
-       cur_state = MMWFDSINK_CURRENT_STATE(wfd);
-       if (cur_state != MM_WFD_SINK_STATE_CONNECTED &&
-               cur_state != MM_WFD_SINK_STATE_PLAYING &&
-               cur_state != MM_WFD_SINK_STATE_PAUSED) {
-
-               wfd_sink_error("This function must be called after MM_WFD_SINK_STATE_CONNECTED");
-               result = MM_ERROR_WFD_INVALID_STATE;
-       } else {
-               *channel = wfd->stream_info.audio_stream_info.channels;
-       }
-
-       MMWFDSINK_CMD_UNLOCK(wfd);
-
-       wfd_sink_debug_fleave();
-
-       return result;
-}
-
-int mm_wfd_sink_get_negotiated_audio_sample_rate(MMHandleType wfd_sink,  gint *sample_rate)
-{
-       int result = MM_ERROR_NONE;
-       mm_wfd_sink_t *wfd = (mm_wfd_sink_t *)wfd_sink;
-       MMWFDSinkStateType cur_state = MM_WFD_SINK_STATE_NONE;
-
-       wfd_sink_debug_fenter();
-
-       wfd_sink_return_val_if_fail(wfd, MM_ERROR_WFD_NOT_INITIALIZED);
-       wfd_sink_return_val_if_fail(sample_rate, MM_ERROR_WFD_INVALID_ARGUMENT);
-
-       MMWFDSINK_CMD_LOCK(wfd);
-
-       MMWFDSINK_PRINT_STATE(wfd);
-       cur_state = MMWFDSINK_CURRENT_STATE(wfd);
-       if (cur_state != MM_WFD_SINK_STATE_CONNECTED &&
-               cur_state != MM_WFD_SINK_STATE_PLAYING &&
-               cur_state != MM_WFD_SINK_STATE_PAUSED) {
-
-               wfd_sink_error("This function must be called after MM_WFD_SINK_STATE_CONNECTED");
-               result = MM_ERROR_WFD_INVALID_STATE;
-       } else {
-               *sample_rate = wfd->stream_info.audio_stream_info.sample_rate;
-       }
-
-       MMWFDSINK_CMD_UNLOCK(wfd);
-
-       wfd_sink_debug_fleave();
-
-       return result;
-}
-
-int mm_wfd_sink_get_negotiated_audio_bitwidth(MMHandleType wfd_sink,  gint *bitwidth)
-{
-       int result = MM_ERROR_NONE;
-       mm_wfd_sink_t *wfd = (mm_wfd_sink_t *)wfd_sink;
-       MMWFDSinkStateType cur_state = MM_WFD_SINK_STATE_NONE;
-
-       wfd_sink_debug_fenter();
-
-       wfd_sink_return_val_if_fail(wfd, MM_ERROR_WFD_NOT_INITIALIZED);
-       wfd_sink_return_val_if_fail(bitwidth, MM_ERROR_WFD_INVALID_ARGUMENT);
-
-       MMWFDSINK_CMD_LOCK(wfd);
-
-       MMWFDSINK_PRINT_STATE(wfd);
-       cur_state = MMWFDSINK_CURRENT_STATE(wfd);
-       if (cur_state != MM_WFD_SINK_STATE_CONNECTED &&
-               cur_state != MM_WFD_SINK_STATE_PLAYING &&
-               cur_state != MM_WFD_SINK_STATE_PAUSED) {
-
-               wfd_sink_error("This function must be called after MM_WFD_SINK_STATE_CONNECTED");
-               result = MM_ERROR_WFD_INVALID_STATE;
-       } else {
-               *bitwidth = wfd->stream_info.audio_stream_info.bitwidth;
-       }
-
-       MMWFDSINK_CMD_UNLOCK(wfd);
-
-       wfd_sink_debug_fleave();
-
-       return result;
-}
diff --git a/sink/mm_wfd_sink_manager.c b/sink/mm_wfd_sink_manager.c
deleted file mode 100755 (executable)
index 3eb86f9..0000000
+++ /dev/null
@@ -1,169 +0,0 @@
-/*
- * libmm-wfd
- *
- * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
- *
- * Contact: JongHyuk Choi <jhchoi.choi@samsung.com>, YeJin Cho <cho.yejin@samsung.com>,
- * Seungbae Shin <seungbae.shin@samsung.com>, YoungHwan An <younghwan_.an@samsung.com>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-
-#include "mm_wfd_sink_manager.h"
-
-
-static gpointer __mm_wfd_sink_manager_thread(gpointer data);
-
-int _mm_wfd_sink_init_manager(mm_wfd_sink_t *wfd_sink)
-{
-       wfd_sink_debug_fenter();
-
-       wfd_sink_return_val_if_fail(wfd_sink, MM_ERROR_WFD_NOT_INITIALIZED);
-
-       /* create manager mutex */
-       g_mutex_init(&(wfd_sink->manager_thread_mutex));
-
-       /* create capture cond */
-       g_cond_init(&(wfd_sink->manager_thread_cond));
-
-       wfd_sink->manager_thread_cmd = NULL;
-       wfd_sink->manager_thread_exit = FALSE;
-
-       /* create manager thread */
-       wfd_sink->manager_thread =
-           g_thread_new("__mm_wfd_sink_manager_thread", __mm_wfd_sink_manager_thread, (gpointer)wfd_sink);
-       if (wfd_sink->manager_thread == NULL) {
-               wfd_sink_error("failed to create manager thread\n");
-               goto failed_to_init;
-       }
-
-       wfd_sink_debug_fleave();
-
-       return MM_ERROR_NONE;
-
-failed_to_init:
-       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)
-{
-       wfd_sink_debug_fenter();
-
-       wfd_sink_return_val_if_fail(wfd_sink, MM_ERROR_WFD_NOT_INITIALIZED);
-
-       /* release manager thread */
-       if (wfd_sink->manager_thread) {
-               WFD_SINK_MANAGER_APPEND_CMD(wfd_sink, WFD_SINK_MANAGER_CMD_EXIT);
-               WFD_SINK_MANAGER_SIGNAL_CMD(wfd_sink);
-
-               wfd_sink_debug("waitting for manager thread exit");
-               g_thread_join(wfd_sink->manager_thread);
-               g_mutex_clear(&(wfd_sink->manager_thread_mutex));
-               g_cond_clear(&(wfd_sink->manager_thread_cond));
-               wfd_sink_debug("manager thread released");
-       }
-
-       wfd_sink_debug_fleave();
-
-       return MM_ERROR_NONE;
-}
-
-static gpointer
-__mm_wfd_sink_manager_thread(gpointer data)
-{
-       mm_wfd_sink_t *wfd_sink = (mm_wfd_sink_t *) data;
-       WFDSinkManagerCMDType cmd = WFD_SINK_MANAGER_CMD_NONE;
-       GList *walk = NULL;
-
-       wfd_sink_debug_fenter();
-
-       wfd_sink_return_val_if_fail(wfd_sink, NULL);
-
-       if (wfd_sink->manager_thread_exit) {
-               wfd_sink_debug("exit manager thread...");
-               return NULL;
-       }
-
-       wfd_sink_debug("manager thread started. waiting for signal");
-
-       while (TRUE) {
-               WFD_SINK_MANAGER_LOCK(wfd_sink);
-               WFD_SINK_MANAGER_WAIT_CMD(wfd_sink);
-
-               for (walk = wfd_sink->manager_thread_cmd; walk; walk = g_list_next(walk)) {
-                       cmd = GPOINTER_TO_INT(walk->data);
-
-                       wfd_sink_debug("got command %d", cmd);
-
-                       switch (cmd) {
-                               case WFD_SINK_MANAGER_CMD_LINK_A_DECODEBIN:
-                                       wfd_sink_debug("try to link audio decodebin.");
-                                       if (MM_ERROR_NONE != __mm_wfd_sink_link_audio_decodebin(wfd_sink)) {
-                                               wfd_sink_error("failed to link audio decodebin.....\n");
-                                               goto EXIT;
-                                       }
-                                       break;
-                               case WFD_SINK_MANAGER_CMD_LINK_V_DECODEBIN:
-                                       wfd_sink_debug("try to link video decodebin.");
-                                       if (MM_ERROR_NONE != __mm_wfd_sink_link_video_decodebin(wfd_sink)) {
-                                               wfd_sink_error("failed to link video decodebin.....\n");
-                                               goto EXIT;
-                                       }
-                                       break;
-                               case WFD_SINK_MANAGER_CMD_PREPARE_A_PIPELINE:
-                                       wfd_sink_debug("try to prepare audio pipeline.");
-                                       if (MM_ERROR_NONE != __mm_wfd_sink_prepare_audio_pipeline(wfd_sink)) {
-                                               wfd_sink_error("failed to prepare audio pipeline.....\n");
-                                               goto EXIT;
-                                       }
-                                       break;
-                               case WFD_SINK_MANAGER_CMD_PREPARE_V_PIPELINE:
-                                       wfd_sink_debug("try to prepare video pipeline.");
-                                       if (MM_ERROR_NONE != __mm_wfd_sink_prepare_video_pipeline(wfd_sink)) {
-                                               wfd_sink_error("failed to prepare video pipeline.....\n");
-                                               goto EXIT;
-                                       }
-                                       break;
-                               case WFD_SINK_MANAGER_CMD_EXIT:
-                                       wfd_sink_debug("exiting manager thread");
-                                       goto EXIT;
-                                       break;
-                               default:
-                                       break;
-                       }
-               }
-
-               g_list_free(wfd_sink->manager_thread_cmd);
-               wfd_sink->manager_thread_cmd = NULL;
-
-               WFD_SINK_MANAGER_UNLOCK(wfd_sink);
-       }
-
-       wfd_sink_debug_fleave();
-
-       return NULL;
-
-EXIT:
-       wfd_sink->manager_thread_exit = TRUE;
-       g_list_free(wfd_sink->manager_thread_cmd);
-       wfd_sink->manager_thread_cmd = NULL;
-       WFD_SINK_MANAGER_UNLOCK(wfd_sink);
-
-       return NULL;
-}
-
diff --git a/sink/mm_wfd_sink_priv.c b/sink/mm_wfd_sink_priv.c
deleted file mode 100755 (executable)
index 0dbfd66..0000000
+++ /dev/null
@@ -1,3690 +0,0 @@
-/*
- * libmm-wfd
- *
- * Copyright (c) 2011 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
- *
- * Contact: JongHyuk Choi <jhchoi.choi@samsung.com>, ByungWook Jang <bw.jang@samsung.com>,
- * Maksym Ukhanov <m.ukhanov@samsung.com>, Hyunjun Ko <zzoon.ko@samsung.com>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-#include <gst/gst.h>
-#include <gst/video/videooverlay.h>
-#include <Elementary.h>
-#include <Ecore_Wayland.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"
-#include "mm_wfd_sink_wfd_enum.h"
-#include "mm_wfd_sink_wayland.h"
-
-
-/* gstreamer */
-static int __mm_wfd_sink_init_gstreamer(mm_wfd_sink_t *wfd_sink);
-static int __mm_wfd_sink_create_pipeline(mm_wfd_sink_t *wfd_sink);
-static int __mm_wfd_sink_create_audio_decodebin(mm_wfd_sink_t *wfd_sink);
-static int __mm_wfd_sink_create_video_decodebin(mm_wfd_sink_t *wfd_sink);
-static int __mm_wfd_sink_destroy_audio_decodebin(mm_wfd_sink_t *wfd_sink);
-static int __mm_wfd_sink_destroy_video_decodebin(mm_wfd_sink_t *wfd_sink);
-static int __mm_wfd_sink_create_video_sinkbin(mm_wfd_sink_t *wfd_sink);
-static int __mm_wfd_sink_create_audio_sinkbin(mm_wfd_sink_t *wfd_sink);
-static int __mm_wfd_sink_destroy_pipeline(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);
-
-/* util */
-static void __mm_wfd_sink_dump_pipeline_state(mm_wfd_sink_t *wfd_sink);
-static void __mm_wfd_sink_prepare_video_resolution(gint resolution, guint *CEA_resolution, guint *VESA_resolution, guint *HH_resolution);
-
-int _mm_wfd_sink_create(mm_wfd_sink_t **wfd_sink)
-{
-       int result = MM_ERROR_NONE;
-
-       wfd_sink_debug_fenter();
-
-       wfd_sink_return_val_if_fail(wfd_sink, MM_ERROR_WFD_NOT_INITIALIZED);
-
-       mm_wfd_sink_t *new_wfd_sink = NULL;
-
-       /* create handle */
-       new_wfd_sink = g_malloc0(sizeof(mm_wfd_sink_t));
-       if (!new_wfd_sink) {
-               wfd_sink_error("failed to allocate memory for wi-fi display sink");
-               return MM_ERROR_WFD_NO_FREE_SPACE;
-       }
-
-       /* Initialize gstreamer related */
-       new_wfd_sink->attrs = 0;
-
-       new_wfd_sink->pipeline = NULL;
-       new_wfd_sink->audio_decodebin_is_linked = FALSE;
-       new_wfd_sink->video_decodebin_is_linked = FALSE;
-
-       /* Initialize timestamp compensation related */
-       new_wfd_sink->need_to_reset_basetime = FALSE;
-       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;
-       MMWFDSINK_PENDING_STATE(new_wfd_sink) =  MM_WFD_SINK_STATE_NONE;
-
-       /* initialize audio/video information */
-       new_wfd_sink->stream_info.audio_stream_info.codec = MM_WFD_SINK_AUDIO_CODEC_NONE;
-       new_wfd_sink->stream_info.audio_stream_info.channels = 0;
-       new_wfd_sink->stream_info.audio_stream_info.sample_rate = 0;
-       new_wfd_sink->stream_info.audio_stream_info.bitwidth = 0;
-       new_wfd_sink->stream_info.video_stream_info.codec = MM_WFD_SINK_VIDEO_CODEC_NONE;
-       new_wfd_sink->stream_info.video_stream_info.width = 0;
-       new_wfd_sink->stream_info.video_stream_info.height = 0;
-       new_wfd_sink->stream_info.video_stream_info.frame_rate = 0;
-
-       /* Initialize command */
-       new_wfd_sink->cmd = MM_WFD_SINK_COMMAND_CREATE;
-       new_wfd_sink->waiting_cmd = FALSE;
-
-       /* Initialize manager related */
-       new_wfd_sink->manager_thread = NULL;
-       new_wfd_sink->manager_thread_cmd = NULL;
-       new_wfd_sink->manager_thread_exit = FALSE;
-
-       /* Initialize video resolution */
-       new_wfd_sink->supportive_resolution = MM_WFD_SINK_RESOLUTION_UNKNOWN;
-
-       /* construct attributes */
-       new_wfd_sink->attrs = _mmwfd_construct_attribute((MMHandleType)new_wfd_sink);
-       if (!new_wfd_sink->attrs) {
-               MMWFDSINK_FREEIF(new_wfd_sink);
-               wfd_sink_error("failed to set attribute");
-               return MM_ERROR_WFD_INTERNAL;
-       }
-
-       /* load ini for initialize */
-       result = mm_wfd_sink_ini_load(&new_wfd_sink->ini);
-       if (result != MM_ERROR_NONE) {
-               wfd_sink_error("failed to load ini file");
-               goto fail_to_load_ini;
-       }
-       new_wfd_sink->need_to_reset_basetime = new_wfd_sink->ini.enable_reset_basetime;
-
-       /* initialize manager */
-       result = _mm_wfd_sink_init_manager(new_wfd_sink);
-       if (result < MM_ERROR_NONE) {
-               wfd_sink_error("failed to init manager : %d", result);
-               goto fail_to_init;
-       }
-
-       /* initialize gstreamer */
-       result = __mm_wfd_sink_init_gstreamer(new_wfd_sink);
-       if (result < MM_ERROR_NONE) {
-               wfd_sink_error("failed to init gstreamer : %d", result);
-               goto fail_to_init;
-       }
-
-       /* set state */
-       __mm_wfd_sink_set_state(new_wfd_sink,  MM_WFD_SINK_STATE_NULL);
-
-       /* now take handle */
-       *wfd_sink = new_wfd_sink;
-
-       wfd_sink_debug_fleave();
-
-       return result;
-
-       /* ERRORS */
-fail_to_init:
-       mm_wfd_sink_ini_unload(&new_wfd_sink->ini);
-fail_to_load_ini:
-       _mmwfd_deconstruct_attribute(new_wfd_sink->attrs);
-       MMWFDSINK_FREEIF(new_wfd_sink);
-
-       *wfd_sink = NULL;
-
-       return result;
-}
-
-int _mm_wfd_sink_prepare(mm_wfd_sink_t *wfd_sink)
-{
-       int result = MM_ERROR_NONE;
-
-       wfd_sink_debug_fenter();
-
-       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_PREPARE);
-
-       /* construct pipeline */
-       /* create main pipeline */
-       result = __mm_wfd_sink_create_pipeline(wfd_sink);
-       if (result < MM_ERROR_NONE) {
-               wfd_sink_error("failed to create pipeline : %d", result);
-               goto fail_to_create;
-       }
-
-       /* create video decodebin */
-       result = __mm_wfd_sink_create_video_decodebin(wfd_sink);
-       if (result < MM_ERROR_NONE) {
-               wfd_sink_error("failed to create video decodebin %d", result);
-               goto fail_to_create;
-       }
-
-       /* create video sinkbin */
-       result = __mm_wfd_sink_create_video_sinkbin(wfd_sink);
-       if (result < MM_ERROR_NONE) {
-               wfd_sink_error("failed to create video sinkbin %d", result);
-               goto fail_to_create;
-       }
-
-       /* create audio decodebin */
-       result = __mm_wfd_sink_create_audio_decodebin(wfd_sink);
-       if (result < MM_ERROR_NONE) {
-               wfd_sink_error("fail to create audio decodebin : %d", result);
-               goto fail_to_create;
-       }
-
-       /* create audio sinkbin */
-       result = __mm_wfd_sink_create_audio_sinkbin(wfd_sink);
-       if (result < MM_ERROR_NONE) {
-               wfd_sink_error("fail to create audio sinkbin : %d", result);
-               goto fail_to_create;
-       }
-
-       /* set pipeline READY state */
-       result = __mm_wfd_sink_set_pipeline_state(wfd_sink, GST_STATE_READY, TRUE);
-       if (result < MM_ERROR_NONE) {
-               wfd_sink_error("failed to set state : %d", result);
-               goto fail_to_create;
-       }
-
-       /* set state */
-       __mm_wfd_sink_set_state(wfd_sink,  MM_WFD_SINK_STATE_PREPARED);
-
-       wfd_sink_debug_fleave();
-
-       return result;
-
-       /* ERRORS */
-fail_to_create:
-       /* need to destroy pipeline already created */
-       __mm_wfd_sink_destroy_pipeline(wfd_sink);
-       return result;
-}
-
-int _mm_wfd_sink_connect(mm_wfd_sink_t *wfd_sink, const char *uri)
-{
-       int result = MM_ERROR_NONE;
-
-       wfd_sink_debug_fenter();
-
-       wfd_sink_return_val_if_fail(uri && strlen(uri) > strlen("rtsp://"), MM_ERROR_WFD_INVALID_ARGUMENT);
-       wfd_sink_return_val_if_fail(wfd_sink &&
-                                               wfd_sink->pipeline &&
-                                               wfd_sink->pipeline->mainbin &&
-                                               wfd_sink->pipeline->mainbin[WFD_SINK_M_PIPE].gst &&
-                                               wfd_sink->pipeline->mainbin[WFD_SINK_M_SRC].gst &&
-                                               wfd_sink->pipeline->mainbin[WFD_SINK_M_DEPAY].gst &&
-                                               wfd_sink->pipeline->mainbin[WFD_SINK_M_DEMUX].gst,
-                                               MM_ERROR_WFD_NOT_INITIALIZED);
-
-       /* check current wi-fi display sink state */
-       MMWFDSINK_CHECK_STATE(wfd_sink, MM_WFD_SINK_COMMAND_CONNECT);
-
-       wfd_sink_debug("try to connect to %s.....", GST_STR_NULL(uri));
-
-       /* set uri to wfdsrc */
-       g_object_set(G_OBJECT(wfd_sink->pipeline->mainbin[WFD_SINK_M_SRC].gst), "location", uri, NULL);
-
-       /* set pipeline PAUSED state */
-       result = __mm_wfd_sink_set_pipeline_state(wfd_sink, GST_STATE_PAUSED, TRUE);
-       if (result < MM_ERROR_NONE) {
-               wfd_sink_error("failed to set state : %d", result);
-               return result;
-       }
-
-       wfd_sink_debug_fleave();
-
-       return result;
-}
-
-int _mm_wfd_sink_start(mm_wfd_sink_t *wfd_sink)
-{
-       int result = MM_ERROR_NONE;
-
-       wfd_sink_debug_fenter();
-
-       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);
-
-       WFD_SINK_MANAGER_LOCK(wfd_sink) ;
-       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) {
-               wfd_sink_error("failed to set state : %d", result);
-               return result;
-       }
-
-       wfd_sink_debug_fleave();
-
-       return result;
-}
-
-int _mm_wfd_sink_pause(mm_wfd_sink_t *wfd_sink)
-{
-       int result = MM_ERROR_NONE;
-
-       wfd_sink_debug_fenter();
-
-       wfd_sink_return_val_if_fail(wfd_sink &&
-                                               wfd_sink->pipeline &&
-                                               wfd_sink->pipeline->mainbin &&
-                                               wfd_sink->pipeline->mainbin[WFD_SINK_M_PIPE].gst &&
-                                               wfd_sink->pipeline->mainbin[WFD_SINK_M_SRC].gst,
-                                               MM_ERROR_WFD_NOT_INITIALIZED);
-
-       /* check current wi-fi display sink state */
-       MMWFDSINK_CHECK_STATE(wfd_sink, MM_WFD_SINK_COMMAND_PAUSE);
-
-       g_signal_emit_by_name(wfd_sink->pipeline->mainbin[WFD_SINK_M_SRC].gst, "pause", NULL);
-
-       wfd_sink_debug_fleave();
-
-       return result;
-}
-
-int _mm_wfd_sink_resume(mm_wfd_sink_t *wfd_sink)
-{
-       int result = MM_ERROR_NONE;
-
-       wfd_sink_debug_fenter();
-
-       wfd_sink_return_val_if_fail(wfd_sink &&
-                                               wfd_sink->pipeline &&
-                                               wfd_sink->pipeline->mainbin &&
-                                               wfd_sink->pipeline->mainbin[WFD_SINK_M_PIPE].gst &&
-                                               wfd_sink->pipeline->mainbin[WFD_SINK_M_SRC].gst,
-                                               MM_ERROR_WFD_NOT_INITIALIZED);
-
-       /* check current wi-fi display sink state */
-       MMWFDSINK_CHECK_STATE(wfd_sink, MM_WFD_SINK_COMMAND_RESUME);
-
-       g_signal_emit_by_name(wfd_sink->pipeline->mainbin[WFD_SINK_M_SRC].gst, "resume", NULL);
-
-       wfd_sink_debug_fleave();
-
-       return result;
-}
-
-int _mm_wfd_sink_disconnect(mm_wfd_sink_t *wfd_sink)
-{
-       int result = MM_ERROR_NONE;
-
-       wfd_sink_debug_fenter();
-
-       wfd_sink_return_val_if_fail(wfd_sink &&
-                                               wfd_sink->pipeline &&
-                                               wfd_sink->pipeline->mainbin &&
-                                               wfd_sink->pipeline->mainbin[WFD_SINK_M_PIPE].gst &&
-                                               wfd_sink->pipeline->mainbin[WFD_SINK_M_SRC].gst,
-                                               MM_ERROR_WFD_NOT_INITIALIZED);
-
-       /* check current wi-fi display sink state */
-       MMWFDSINK_CHECK_STATE(wfd_sink, MM_WFD_SINK_COMMAND_DISCONNECT);
-
-       WFD_SINK_MANAGER_APPEND_CMD(wfd_sink, WFD_SINK_MANAGER_CMD_EXIT);
-       WFD_SINK_MANAGER_SIGNAL_CMD(wfd_sink);
-
-       g_signal_emit_by_name(wfd_sink->pipeline->mainbin[WFD_SINK_M_SRC].gst, "close", NULL);
-
-       wfd_sink_debug_fleave();
-
-       return result;
-}
-
-int _mm_wfd_sink_unprepare(mm_wfd_sink_t *wfd_sink)
-{
-       int result = MM_ERROR_NONE;
-
-       wfd_sink_debug_fenter();
-
-       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_UNPREPARE);
-
-       WFD_SINK_MANAGER_APPEND_CMD(wfd_sink, WFD_SINK_MANAGER_CMD_EXIT);
-       WFD_SINK_MANAGER_SIGNAL_CMD(wfd_sink);
-
-       /* release pipeline */
-       result =  __mm_wfd_sink_destroy_pipeline(wfd_sink);
-       if (result != MM_ERROR_NONE) {
-               wfd_sink_error("failed to destory pipeline");
-               return MM_ERROR_WFD_INTERNAL;
-       } else {
-               wfd_sink_debug("success to destory pipeline");
-       }
-
-       /* set state */
-       __mm_wfd_sink_set_state(wfd_sink,  MM_WFD_SINK_STATE_NULL);
-
-       wfd_sink_debug_fleave();
-
-       return result;
-}
-
-int _mm_wfd_sink_destroy(mm_wfd_sink_t *wfd_sink)
-{
-       int result = MM_ERROR_NONE;
-
-       wfd_sink_debug_fenter();
-
-       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);
-
-       /* unload ini */
-       mm_wfd_sink_ini_unload(&wfd_sink->ini);
-
-       /* release attributes */
-       _mmwfd_deconstruct_attribute(wfd_sink->attrs);
-
-       if (MM_ERROR_NONE != _mm_wfd_sink_release_manager(wfd_sink)) {
-               wfd_sink_error("failed to release manager");
-               return MM_ERROR_WFD_INTERNAL;
-       }
-
-
-       /* set state */
-       __mm_wfd_sink_set_state(wfd_sink,  MM_WFD_SINK_STATE_NONE);
-
-       wfd_sink_debug_fleave();
-
-       return result;
-}
-
-int _mm_wfd_set_message_callback(mm_wfd_sink_t *wfd_sink, MMWFDMessageCallback callback, void *user_data)
-{
-       int result = MM_ERROR_NONE;
-
-       wfd_sink_debug_fenter();
-
-       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;
-
-       wfd_sink_debug_fleave();
-
-       return result;
-}
-
-static int __mm_wfd_sink_init_gstreamer(mm_wfd_sink_t *wfd_sink)
-{
-       int result = MM_ERROR_NONE;
-       gint *argc = NULL;
-       gchar **argv = NULL;
-       static const int max_argc = 50;
-       GError *err = NULL;
-       gint i = 0;
-
-       wfd_sink_debug_fenter();
-
-       /* alloc */
-       argc = calloc(1, sizeof(gint));
-       argv = calloc(max_argc, sizeof(gchar *));
-       if (!argc || !argv) {
-               wfd_sink_error("failed to allocate memory for wfdsink");
-
-               MMWFDSINK_FREEIF(argv);
-               MMWFDSINK_FREEIF(argc);
-
-               return MM_ERROR_WFD_NO_FREE_SPACE;
-       }
-
-       /* we would not do fork for scanning plugins */
-       argv[*argc] = g_strdup("--gst-disable-registry-fork");
-       (*argc)++;
-
-       /* check disable registry scan */
-       argv[*argc] = g_strdup("--gst-disable-registry-update");
-       (*argc)++;
-
-       /* check disable segtrap */
-       argv[*argc] = g_strdup("--gst-disable-segtrap");
-       (*argc)++;
-
-       /* check ini */
-       for (i = 0; i < 5; i++) {
-               if (strlen(wfd_sink->ini.gst_param[i]) > 2) {
-                       wfd_sink_debug("set %s", wfd_sink->ini.gst_param[i]);
-                       argv[*argc] = g_strdup(wfd_sink->ini.gst_param[i]);
-                       (*argc)++;
-               }
-       }
-
-       wfd_sink_debug("initializing gstreamer with following parameter");
-       wfd_sink_debug("argc : %d", *argc);
-
-       for (i = 0; i < *argc; i++) {
-               wfd_sink_debug("argv[%d] : %s", i, argv[i]);
-       }
-
-       /* initializing gstreamer */
-       if (!gst_init_check(argc, &argv, &err)) {
-               wfd_sink_error("failed to initialize gstreamer: %s", err ? err->message : "unknown error occurred");
-               if (err)
-                       g_error_free(err);
-
-               result = MM_ERROR_WFD_INTERNAL;
-       }
-
-       /* release */
-       for (i = 0; i < *argc; i++) {
-               MMWFDSINK_FREEIF(argv[i]);
-       }
-       MMWFDSINK_FREEIF(argv);
-       MMWFDSINK_FREEIF(argc);
-
-       wfd_sink_debug_fleave();
-
-       return result;
-}
-
-static GstBusSyncReply
-_mm_wfd_bus_sync_callback(GstBus *bus, GstMessage *message, gpointer 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:
-                       break;
-               case GST_MESSAGE_DURATION:
-                       break;
-               case GST_MESSAGE_STATE_CHANGED: {
-                               /* 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 (!GST_IS_PIPELINE(GST_MESSAGE_SRC(message)))
-                                       ret = GST_BUS_DROP;
-                       }
-                       break;
-               default:
-                       break;
-       }
-
-       return ret;
-}
-
-static gboolean
-_mm_wfd_sink_msg_callback(GstBus *bus, GstMessage *msg, gpointer data)
-{
-       mm_wfd_sink_t *wfd_sink = (mm_wfd_sink_t *) data;
-       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);
-
-       wfd_sink_debug("got %s from %s",
-                                       GST_STR_NULL(GST_MESSAGE_TYPE_NAME(msg)),
-                                       GST_STR_NULL(GST_OBJECT_NAME(GST_MESSAGE_SRC(msg))));
-
-       switch (GST_MESSAGE_TYPE(msg)) {
-               case GST_MESSAGE_ERROR: {
-                               GError *error = NULL;
-                               gchar *debug = NULL;
-
-                               /* get error code */
-                               gst_message_parse_error(msg, &error, &debug);
-
-                               wfd_sink_error("error : %s", error->message);
-                               wfd_sink_error("debug : %s", debug);
-
-                               MMWFDSINK_FREEIF(debug);
-                               g_error_free(error);
-                       }
-                       break;
-
-               case GST_MESSAGE_WARNING: {
-                               char *debug = NULL;
-                               GError *error = NULL;
-
-                               gst_message_parse_warning(msg, &error, &debug);
-
-                               wfd_sink_warning("warning : %s", error->message);
-                               wfd_sink_warning("debug : %s", debug);
-
-                               MMWFDSINK_FREEIF(debug);
-                               g_error_free(error);
-                       }
-                       break;
-
-               case GST_MESSAGE_STATE_CHANGED: {
-                               const GValue *voldstate, *vnewstate, *vpending;
-                               GstState oldstate, newstate, pending;
-                               const GstStructure *structure;
-
-                               /* we only handle messages from pipeline */
-                               if (msg->src != (GstObject *)wfd_sink->pipeline->mainbin[WFD_SINK_M_PIPE].gst)
-                                       break;
-
-                               /* get state info from msg */
-                               structure = gst_message_get_structure(msg);
-                               if (structure == NULL)
-                                       break;
-
-                               voldstate = gst_structure_get_value(structure, "old-state");
-                               vnewstate = gst_structure_get_value(structure, "new-state");
-                               vpending = gst_structure_get_value(structure, "pending-state");
-                               if (voldstate == NULL || vnewstate == NULL || vpending == NULL)
-                                       break;
-
-                               oldstate = (GstState)voldstate->data[0].v_int;
-                               newstate = (GstState)vnewstate->data[0].v_int;
-                               pending = (GstState)vpending->data[0].v_int;
-
-                               wfd_sink_debug("state changed [%s] : %s--->%s final : %s",
-                                                       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) {
-                                       wfd_sink_debug("pipeline reports state transition to old state");
-                                       break;
-                               }
-
-                               switch (newstate) {
-                                       case GST_STATE_VOID_PENDING:
-                                       case GST_STATE_NULL:
-                                       case GST_STATE_READY:
-                                       case GST_STATE_PAUSED:
-                                       case GST_STATE_PLAYING:
-                                       default:
-                                               break;
-                               }
-                       }
-                       break;
-
-               case GST_MESSAGE_CLOCK_LOST: {
-                               GstClock *clock = NULL;
-                               gst_message_parse_clock_lost(msg, &clock);
-                               wfd_sink_debug("The current clock[%s] as selected by the pipeline became unusable.", (clock ? GST_OBJECT_NAME(clock) : "NULL"));
-                       }
-                       break;
-
-               case GST_MESSAGE_NEW_CLOCK: {
-                               GstClock *clock = NULL;
-                               gst_message_parse_new_clock(msg, &clock);
-                               if (!clock)
-                                       break;
-
-                               if (wfd_sink->clock) {
-                                       if (wfd_sink->clock != clock)
-                                               wfd_sink_debug("clock is changed! [%s] -->[%s]",
-                                                               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]",
-                                                               GST_STR_NULL(GST_OBJECT_NAME(clock)));
-                               } else {
-                                       wfd_sink_debug("new clock [%s] was selected in the pipeline",
-                                                               (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);
-                               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;
-
-                               structure_name = gst_structure_get_name(message_structure);
-                               if (structure_name) {
-                                       wfd_sink_debug("got element specific message[%s]", GST_STR_NULL(structure_name));
-                                       if (g_strrstr(structure_name, "GstUDPSrcTimeout")) {
-                                               wfd_sink_error("Got %s, post error message", GST_STR_NULL(structure_name));
-                                               MMWFDSINK_POST_MESSAGE(wfd_sink,
-                                                                                               MM_ERROR_WFD_INTERNAL,
-                                                                                               MMWFDSINK_CURRENT_STATE(wfd_sink));
-                                       } else if (g_strrstr(structure_name, "GstWFDSrcSessionTimeout")) {
-                                               wfd_sink_error("Got %s, post error message", GST_STR_NULL(structure_name));
-                                               MMWFDSINK_POST_MESSAGE(wfd_sink,
-                                                                                               MM_ERROR_WFD_INTERNAL,
-                                                                                               MMWFDSINK_CURRENT_STATE(wfd_sink));
-                                       }
-                               }
-                       }
-                       break;
-
-               case GST_MESSAGE_PROGRESS: {
-                               GstProgressType type = GST_PROGRESS_TYPE_ERROR;
-                               gchar *category = NULL, *text = NULL;
-
-                               gst_message_parse_progress(msg, &type, &category, &text);
-                               wfd_sink_debug("%s : %s ", GST_STR_NULL(category), GST_STR_NULL(text));
-
-                               switch (type) {
-                                       case GST_PROGRESS_TYPE_START:
-                                               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")) {
-                                                       __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")) {
-                                                       wfd_sink_error("got error : %s", 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")) {
-                                                       wfd_sink_error("got error : %s", 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", 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", 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 {
-                                                       wfd_sink_error("got error : %s", GST_STR_NULL(text));
-                                               }
-                                               break;
-                                       default:
-                                               wfd_sink_error("progress message has no type");
-                                               return ret;
-                               }
-
-                               MMWFDSINK_FREEIF(category);
-                               MMWFDSINK_FREEIF(text);
-                       }
-                       break;
-               case GST_MESSAGE_ASYNC_START:
-                       wfd_sink_debug("GST_MESSAGE_ASYNC_START : %s", gst_element_get_name(GST_MESSAGE_SRC(msg)));
-                       break;
-               case GST_MESSAGE_ASYNC_DONE:
-                       wfd_sink_debug("GST_MESSAGE_ASYNC_DONE : %s", 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:
-                       wfd_sink_debug("unhandled message");
-                       break;
-       }
-
-       return ret;
-}
-
-static int
-__mm_wfd_sink_gst_element_add_bucket_to_bin(GstBin *bin, GList *element_bucket, gboolean need_prepare)
-{
-       GList *bucket = element_bucket;
-       MMWFDSinkGstElement *element = NULL;
-       int successful_add_count = 0;
-
-       wfd_sink_debug_fenter();
-
-       wfd_sink_return_val_if_fail(element_bucket, 0);
-       wfd_sink_return_val_if_fail(bin, 0);
-
-       for (; bucket; bucket = bucket->next) {
-               element = (MMWFDSinkGstElement *)bucket->data;
-
-               if (element && element->gst) {
-                       if (need_prepare)
-                               gst_element_set_state(GST_ELEMENT(element->gst), GST_STATE_READY);
-
-                       if (!gst_bin_add(GST_BIN(bin), GST_ELEMENT(element->gst))) {
-                               wfd_sink_error("failed to add element [%s] to bin [%s]",
-                                               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]",
-                                               GST_STR_NULL(GST_ELEMENT_NAME(GST_ELEMENT(element->gst))),
-                                               GST_STR_NULL(GST_ELEMENT_NAME(GST_ELEMENT_CAST(bin))));
-
-                       successful_add_count++;
-               }
-       }
-
-       wfd_sink_debug_fleave();
-
-       return successful_add_count;
-}
-
-static int
-__mm_wfd_sink_gst_element_link_bucket(GList *element_bucket)
-{
-       GList *bucket = element_bucket;
-       MMWFDSinkGstElement *element = NULL;
-       MMWFDSinkGstElement *prv_element = NULL;
-       gint successful_link_count = 0;
-
-       wfd_sink_debug_fenter();
-
-       wfd_sink_return_val_if_fail(element_bucket, -1);
-
-       prv_element = (MMWFDSinkGstElement *)bucket->data;
-       bucket = bucket->next;
-
-       for (; bucket; bucket = bucket->next) {
-               element = (MMWFDSinkGstElement *)bucket->data;
-
-               if (element && element->gst) {
-                       if (gst_element_link(GST_ELEMENT(prv_element->gst), GST_ELEMENT(element->gst))) {
-                               wfd_sink_debug("linking [%s] to [%s] success",
-                                                       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 {
-                               wfd_sink_error("linking [%s] to [%s] failed",
-                                                       GST_STR_NULL(GST_ELEMENT_NAME(GST_ELEMENT(prv_element->gst))),
-                                                       GST_STR_NULL(GST_ELEMENT_NAME(GST_ELEMENT(element->gst))));
-                               return -1;
-                       }
-               }
-
-               prv_element = element;
-       }
-
-       wfd_sink_debug_fleave();
-
-       return successful_link_count;
-}
-
-static int
-__mm_wfd_sink_check_state(mm_wfd_sink_t *wfd_sink, MMWFDSinkCommandType cmd)
-{
-       MMWFDSinkStateType cur_state = MM_WFD_SINK_STATE_NONE;
-
-       wfd_sink_debug_fenter();
-
-       wfd_sink_return_val_if_fail(wfd_sink, MM_ERROR_WFD_NOT_INITIALIZED);
-
-       MMWFDSINK_PRINT_STATE(wfd_sink);
-
-       cur_state = MMWFDSINK_CURRENT_STATE(wfd_sink);
-
-       switch (cmd) {
-               case MM_WFD_SINK_COMMAND_CREATE: {
-                               if (cur_state != MM_WFD_SINK_STATE_NONE)
-                                       goto invalid_state;
-
-                               MMWFDSINK_PENDING_STATE(wfd_sink) = MM_WFD_SINK_STATE_NULL;
-                       }
-                       break;
-
-               case MM_WFD_SINK_COMMAND_PREPARE: {
-                               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_PREPARED;
-                       }
-                       break;
-
-               case MM_WFD_SINK_COMMAND_CONNECT: {
-                               if (cur_state == MM_WFD_SINK_STATE_CONNECTED)
-                                       goto no_operation;
-                               else if (cur_state != MM_WFD_SINK_STATE_PREPARED)
-                                       goto invalid_state;
-
-                               MMWFDSINK_PENDING_STATE(wfd_sink) = MM_WFD_SINK_STATE_CONNECTED;
-                       }
-                       break;
-
-               case MM_WFD_SINK_COMMAND_START: {
-                               if (cur_state == MM_WFD_SINK_STATE_PLAYING)
-                                       goto no_operation;
-                               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_PAUSE: {
-                               if (cur_state == MM_WFD_SINK_STATE_PAUSED)
-                                       goto no_operation;
-                               else if (cur_state != MM_WFD_SINK_STATE_PLAYING)
-                                       goto invalid_state;
-
-                               MMWFDSINK_PENDING_STATE(wfd_sink) = MM_WFD_SINK_STATE_PAUSED;
-                       }
-                       break;
-
-               case MM_WFD_SINK_COMMAND_RESUME: {
-                               if (cur_state == MM_WFD_SINK_STATE_PLAYING)
-                                       goto no_operation;
-                               else if (cur_state != MM_WFD_SINK_STATE_PAUSED)
-                                       goto invalid_state;
-
-                               MMWFDSINK_PENDING_STATE(wfd_sink) = MM_WFD_SINK_STATE_PLAYING;
-                       }
-                       break;
-
-               case MM_WFD_SINK_COMMAND_DISCONNECT: {
-                               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_DISCONNECTED;
-                       }
-                       break;
-
-               case MM_WFD_SINK_COMMAND_UNPREPARE: {
-                               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;
-                       }
-                       break;
-
-               case MM_WFD_SINK_COMMAND_DESTROY: {
-                               if (cur_state == MM_WFD_SINK_STATE_NONE)
-                                       goto no_operation;
-
-                               MMWFDSINK_PENDING_STATE(wfd_sink) = MM_WFD_SINK_STATE_NONE;
-                       }
-                       break;
-
-               default:
-                       break;
-       }
-
-       wfd_sink->cmd = cmd;
-
-       wfd_sink_debug_fleave();
-
-       return MM_ERROR_NONE;
-
-no_operation:
-       wfd_sink_debug("already %s state, nothing to do.", MMWFDSINK_STATE_GET_NAME(cur_state));
-       return MM_ERROR_WFD_NO_OP;
-
-       /* ERRORS */
-invalid_state:
-       wfd_sink_error("current state is invalid.", 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)
-{
-       wfd_sink_debug_fenter();
-
-       wfd_sink_return_val_if_fail(wfd_sink, MM_ERROR_WFD_NOT_INITIALIZED);
-
-       if (MMWFDSINK_CURRENT_STATE(wfd_sink) == state) {
-               wfd_sink_error("already state(%s)", MMWFDSINK_STATE_GET_NAME(state));
-               MMWFDSINK_PENDING_STATE(wfd_sink) = MM_WFD_SINK_STATE_NONE;
-               return MM_ERROR_NONE;
-       }
-
-       /* update wi-fi display state */
-       MMWFDSINK_PREVIOUS_STATE(wfd_sink) = MMWFDSINK_CURRENT_STATE(wfd_sink);
-       MMWFDSINK_CURRENT_STATE(wfd_sink) = state;
-
-       if (MMWFDSINK_CURRENT_STATE(wfd_sink) == MMWFDSINK_PENDING_STATE(wfd_sink))
-               MMWFDSINK_PENDING_STATE(wfd_sink) = MM_WFD_SINK_STATE_NONE;
-
-       /* poset state message to application */
-       MMWFDSINK_POST_MESSAGE(wfd_sink,
-                                               MM_ERROR_NONE,
-                                               MMWFDSINK_CURRENT_STATE(wfd_sink));
-
-       /* print state */
-       MMWFDSINK_PRINT_STATE(wfd_sink);
-
-       wfd_sink_debug_fleave();
-
-       return MM_ERROR_NONE;
-}
-
-static int
-__mm_wfd_sink_set_pipeline_state(mm_wfd_sink_t *wfd_sink, GstState state, gboolean async)
-{
-       GstStateChangeReturn result = GST_STATE_CHANGE_FAILURE;
-       GstState cur_state = GST_STATE_VOID_PENDING;
-       GstState pending_state = GST_STATE_VOID_PENDING;
-
-       wfd_sink_debug_fenter();
-
-       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);
-
-       wfd_sink_return_val_if_fail(state > GST_STATE_VOID_PENDING, MM_ERROR_WFD_INVALID_ARGUMENT);
-
-       wfd_sink_debug("try to set %s state ", 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) {
-               wfd_sink_error("fail to set %s state....", gst_element_state_get_name(state));
-               return MM_ERROR_WFD_INTERNAL;
-       }
-
-       if (!async) {
-               wfd_sink_debug("wait for changing state is completed ");
-
-               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) {
-                       wfd_sink_error("fail to get state within %d seconds....", wfd_sink->ini.state_change_timeout);
-
-                       __mm_wfd_sink_dump_pipeline_state(wfd_sink);
-
-                       return MM_ERROR_WFD_INTERNAL;
-               } else if (result == GST_STATE_CHANGE_NO_PREROLL) {
-                       wfd_sink_debug("successfully changed state but is not able to provide data yet");
-               }
-
-               wfd_sink_debug("cur state is %s, pending state is %s",
-                                       gst_element_state_get_name(cur_state),
-                                       gst_element_state_get_name(pending_state));
-       }
-
-
-       wfd_sink_debug_fleave();
-
-       return MM_ERROR_NONE;
-}
-
-static void
-_mm_wfd_sink_reset_basetime(mm_wfd_sink_t *wfd_sink)
-{
-       GstClockTime base_time = GST_CLOCK_TIME_NONE;
-       int i;
-
-       wfd_sink_debug_fenter();
-
-       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)) {
-
-               wfd_sink_debug("set pipeline base_time as now [%"GST_TIME_FORMAT"]", GST_TIME_ARGS(base_time));
-
-               for (i = 0; i < WFD_SINK_M_NUM; i++) {
-                       if (wfd_sink->pipeline->mainbin[i].gst)
-                               gst_element_set_base_time(GST_ELEMENT_CAST(wfd_sink->pipeline->mainbin[i].gst), base_time);
-               }
-
-               if (wfd_sink->pipeline->v_decodebin) {
-                       for (i = 0; i < WFD_SINK_V_D_NUM; i++) {
-                               if (wfd_sink->pipeline->v_decodebin[i].gst)
-                                       gst_element_set_base_time(GST_ELEMENT_CAST(wfd_sink->pipeline->v_decodebin[i].gst), base_time);
-                       }
-               }
-
-               if (wfd_sink->pipeline->v_sinkbin) {
-                       for (i = 0; i < WFD_SINK_V_S_NUM; i++) {
-                               if (wfd_sink->pipeline->v_sinkbin[i].gst)
-                                       gst_element_set_base_time(GST_ELEMENT_CAST(wfd_sink->pipeline->v_sinkbin[i].gst), base_time);
-                       }
-               }
-
-               if (wfd_sink->pipeline->a_decodebin) {
-                       for (i = 0; i < WFD_SINK_A_D_NUM; i++) {
-                               if (wfd_sink->pipeline->a_decodebin[i].gst)
-                                       gst_element_set_base_time(GST_ELEMENT_CAST(wfd_sink->pipeline->a_decodebin[i].gst), base_time);
-                       }
-               }
-
-               if (wfd_sink->pipeline->a_sinkbin) {
-                       for (i = 0; i < WFD_SINK_A_S_NUM; i++) {
-                               if (wfd_sink->pipeline->a_sinkbin[i].gst)
-                                       gst_element_set_base_time(GST_ELEMENT_CAST(wfd_sink->pipeline->a_sinkbin[i].gst), base_time);
-                       }
-               }
-
-               wfd_sink->need_to_reset_basetime = FALSE;
-       }
-
-       wfd_sink_debug_fleave();
-
-       return;
-}
-
-int
-__mm_wfd_sink_prepare_video_pipeline(mm_wfd_sink_t *wfd_sink)
-{
-       GstElement *bin = NULL;
-
-       wfd_sink_debug_fenter();
-
-       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);
-
-       /* check video decodebin is linked */
-       if (!wfd_sink->video_decodebin_is_linked) {
-               /* check video decodebin is created */
-               if (wfd_sink->pipeline->v_decodebin == NULL) {
-                       if (MM_ERROR_NONE != __mm_wfd_sink_create_video_decodebin(wfd_sink)) {
-                               wfd_sink_error("failed to create video decodebin....");
-                               goto ERROR;
-                       }
-               }
-
-               if (MM_ERROR_NONE != __mm_wfd_sink_link_video_decodebin(wfd_sink)) {
-                       wfd_sink_error("failed to link video decodebin.....");
-                       goto ERROR;
-               }
-       }
-
-       /* check video sinkbin is created */
-       if (wfd_sink->pipeline->v_sinkbin == NULL) {
-               if (MM_ERROR_NONE != __mm_wfd_sink_create_video_sinkbin(wfd_sink)) {
-                       wfd_sink_error("failed to create video sinkbin....");
-                       goto ERROR;
-               }
-       }
-
-       /* set video decodebin state as READY */
-       if (wfd_sink->pipeline->v_decodebin && wfd_sink->pipeline->v_decodebin[WFD_SINK_V_D_BIN].gst) {
-               bin = wfd_sink->pipeline->v_decodebin[WFD_SINK_V_D_BIN].gst;
-               if (GST_STATE(bin) <= GST_STATE_NULL) {
-                       if (GST_STATE_CHANGE_FAILURE == gst_element_set_state(bin, GST_STATE_READY)) {
-                               wfd_sink_error("failed to set state(READY) to video decodebin");
-                               goto ERROR;
-                       }
-               }
-       } else {
-               wfd_sink_warning("going on without video decodebin....");
-       }
-
-       /* set video sinkbin state as READY */
-       if (wfd_sink->pipeline->v_sinkbin && wfd_sink->pipeline->v_sinkbin[WFD_SINK_V_S_BIN].gst) {
-               bin = wfd_sink->pipeline->v_sinkbin[WFD_SINK_V_S_BIN].gst;
-               if (GST_STATE(bin) <= GST_STATE_NULL) {
-                       if (GST_STATE_CHANGE_FAILURE == gst_element_set_state(bin, GST_STATE_READY)) {
-                               wfd_sink_error("failed to set state(READY) to video sinkbin");
-                               goto ERROR;
-                       }
-               }
-       } else {
-               wfd_sink_warning("going on without video sinkbin....");
-       }
-
-       wfd_sink_debug_fleave();
-
-       return MM_ERROR_NONE;
-
-       /* ERRORS */
-ERROR:
-       /* need to notify to app */
-       MMWFDSINK_POST_MESSAGE(wfd_sink,
-                                               MM_ERROR_WFD_INTERNAL,
-                                               MMWFDSINK_CURRENT_STATE(wfd_sink));
-
-       return MM_ERROR_WFD_INTERNAL;
-}
-
-int __mm_wfd_sink_prepare_audio_pipeline(mm_wfd_sink_t *wfd_sink)
-{
-       GstElement *bin  = NULL;
-
-       wfd_sink_debug_fenter();
-
-       wfd_sink_return_val_if_fail(wfd_sink &&
-                                               wfd_sink->pipeline,
-                                               MM_ERROR_WFD_NOT_INITIALIZED);
-
-       /* check audio decodebin is linked */
-       if (!wfd_sink->audio_decodebin_is_linked) {
-               /* check audio decodebin is created */
-               if (wfd_sink->pipeline->a_decodebin == NULL) {
-                       if (MM_ERROR_NONE != __mm_wfd_sink_create_audio_decodebin(wfd_sink)) {
-                               wfd_sink_error("failed to create audio decodebin....");
-                               goto ERROR;
-                       }
-               }
-
-               if (MM_ERROR_NONE != __mm_wfd_sink_link_audio_decodebin(wfd_sink)) {
-                       wfd_sink_error("failed to link audio decodebin.....");
-                       goto ERROR;
-               }
-       }
-
-       /* check audio sinkbin is created */
-       if (wfd_sink->pipeline->a_sinkbin == NULL) {
-               if (MM_ERROR_NONE != __mm_wfd_sink_create_audio_sinkbin(wfd_sink)) {
-                       wfd_sink_error("failed to create audio sinkbin....");
-                       goto ERROR;
-               }
-       }
-
-       /* set audio decodebin state as READY */
-       if (wfd_sink->pipeline->a_decodebin && wfd_sink->pipeline->a_decodebin[WFD_SINK_A_D_BIN].gst) {
-               bin  = wfd_sink->pipeline->a_decodebin[WFD_SINK_A_D_BIN].gst;
-               if (GST_STATE(bin) <= GST_STATE_NULL) {
-                       if (GST_STATE_CHANGE_FAILURE == gst_element_set_state(bin, GST_STATE_READY)) {
-                               wfd_sink_error("failed to set state(READY) to audio decodebin");
-                               goto ERROR;
-                       }
-               }
-       } else {
-               wfd_sink_warning("going on without audio decodebin....");
-       }
-
-       /* set audio sinkbin state as READY */
-       if (wfd_sink->pipeline->a_sinkbin && wfd_sink->pipeline->a_sinkbin[WFD_SINK_A_S_BIN].gst) {
-               bin = wfd_sink->pipeline->a_sinkbin[WFD_SINK_A_S_BIN].gst;
-               if (GST_STATE(bin) <= GST_STATE_NULL) {
-                       if (GST_STATE_CHANGE_FAILURE == gst_element_set_state(bin , GST_STATE_READY)) {
-                               wfd_sink_error("failed to set state(READY) to audio sinkbin");
-                               goto ERROR;
-                       }
-               }
-       } else {
-               wfd_sink_warning("going on without audio sinkbin....");
-       }
-
-       wfd_sink_debug_fleave();
-
-       return MM_ERROR_NONE;
-
-       /* ERRORS */
-ERROR:
-       /* need to notify to app */
-       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;
-
-       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");
-               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->v_sinkbin[WFD_SINK_V_S_BIN].gst);
-       else if (g_strrstr(GST_OBJECT_NAME(pad), "audio"))
-               base_time = gst_element_get_base_time(wfd_sink->pipeline->a_sinkbin[WFD_SINK_A_S_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"", 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_warning("buffer timestamp is invalid.");
-               return GST_PAD_PROBE_OK;
-       }
-
-       if (g_strrstr(GST_OBJECT_NAME(pad), "audio")) {
-               if (wfd_sink->pipeline && wfd_sink->pipeline->a_sinkbin && wfd_sink->pipeline->a_sinkbin[WFD_SINK_A_S_SINK].gst)
-                       g_object_get(G_OBJECT(wfd_sink->pipeline->a_sinkbin[WFD_SINK_A_S_SINK].gst), "ts-offset", &ts_offset, NULL);
-       } else if (g_strrstr(GST_OBJECT_NAME(pad), "video")) {
-               if (wfd_sink->pipeline && wfd_sink->pipeline->v_sinkbin && wfd_sink->pipeline->v_sinkbin[WFD_SINK_V_S_SINK].gst)
-                       g_object_get(G_OBJECT(wfd_sink->pipeline->v_sinkbin[WFD_SINK_V_S_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 "",
-                                               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.. ");
-               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) ", 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"",
-                                                       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) ", 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"",
-                                                       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 ",
-                                               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")",
-                                               minus_compensation ? "-" : "", avgrage_gap_diff,
-                                               GST_TIME_ARGS(ts_offset), GST_TIME_ARGS(running_time));
-
-                               if (wfd_sink->pipeline && wfd_sink->pipeline->a_sinkbin && wfd_sink->pipeline->a_sinkbin[WFD_SINK_A_S_SINK].gst)
-                                       g_object_set(G_OBJECT(wfd_sink->pipeline->a_sinkbin[WFD_SINK_A_S_SINK].gst), "ts-offset", (gint64)ts_offset, NULL);
-                               if (wfd_sink->pipeline && wfd_sink->pipeline->v_sinkbin && wfd_sink->pipeline->v_sinkbin[WFD_SINK_V_S_SINK].gst)
-                                       g_object_set(G_OBJECT(wfd_sink->pipeline->v_sinkbin[WFD_SINK_V_S_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 ")",
-                                               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,
-                                       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)
-{
-       mm_wfd_sink_t *wfd_sink = (mm_wfd_sink_t *)data;
-       gchar *name = gst_pad_get_name(pad);
-       GstElement *pipeline = NULL;
-       GstElement *decodebin = NULL;
-       GstElement *sinkbin = NULL;
-       GstPad *sinkpad = NULL;
-       GstPad *srcpad = NULL;
-
-       wfd_sink_debug_fenter();
-
-       wfd_sink_return_if_fail(wfd_sink &&
-                                       wfd_sink->pipeline &&
-                                       wfd_sink->pipeline->mainbin &&
-                                       wfd_sink->pipeline->mainbin[WFD_SINK_M_PIPE].gst);
-
-       pipeline = wfd_sink->pipeline->mainbin[WFD_SINK_M_PIPE].gst;
-
-       /* take decodebin/sinkbin */
-       if (name[0] == 'v') {
-               wfd_sink_debug("=========== >>>>>>>>>> Received VIDEO pad...");
-
-               MMWFDSINK_PAD_PROBE(wfd_sink, pad, NULL,  NULL);
-
-               gst_pad_add_probe(pad,
-                                       GST_PAD_PROBE_TYPE_BUFFER,
-                                       _mm_wfd_sink_check_running_time,
-                                       (gpointer)wfd_sink,
-                                       NULL);
-
-               if (MM_ERROR_NONE != __mm_wfd_sink_prepare_video_pipeline(wfd_sink)) {
-                       wfd_sink_error("failed to prepare video pipeline....");
-                       goto ERROR;
-               }
-
-               if (wfd_sink->pipeline->v_decodebin && wfd_sink->pipeline->v_decodebin[WFD_SINK_V_D_BIN].gst)
-                       decodebin = wfd_sink->pipeline->v_decodebin[WFD_SINK_V_D_BIN].gst;
-               if (wfd_sink->pipeline->v_sinkbin && wfd_sink->pipeline->v_sinkbin[WFD_SINK_V_S_BIN].gst)
-                       sinkbin = wfd_sink->pipeline->v_sinkbin[WFD_SINK_V_S_BIN].gst;
-       } else if (name[0] == 'a') {
-               wfd_sink_debug("=========== >>>>>>>>>> Received AUDIO pad...");
-
-               MMWFDSINK_PAD_PROBE(wfd_sink, pad, NULL,  NULL);
-
-               gst_pad_add_probe(pad,
-                                       GST_PAD_PROBE_TYPE_BUFFER,
-                                       _mm_wfd_sink_check_running_time,
-                                       (gpointer)wfd_sink,
-                                       NULL);
-
-               if (MM_ERROR_NONE != __mm_wfd_sink_prepare_audio_pipeline(wfd_sink)) {
-                       wfd_sink_error("failed to prepare audio pipeline....");
-                       goto ERROR;
-               }
-
-               if (wfd_sink->pipeline->a_decodebin && wfd_sink->pipeline->a_decodebin[WFD_SINK_A_D_BIN].gst)
-                       decodebin = wfd_sink->pipeline->a_decodebin[WFD_SINK_A_D_BIN].gst;
-               if (wfd_sink->pipeline->a_sinkbin && wfd_sink->pipeline->a_sinkbin[WFD_SINK_A_S_BIN].gst)
-                       sinkbin = wfd_sink->pipeline->a_sinkbin[WFD_SINK_A_S_BIN].gst;
-       } else {
-               wfd_sink_error("unexceptable pad is added!!!");
-               return;
-       }
-
-       srcpad = gst_object_ref(pad);
-
-       /* add decodebin and link */
-       if (decodebin) {
-               if (!gst_bin_add(GST_BIN(pipeline), decodebin)) {
-                       wfd_sink_error("failed to add %s to pipeline",
-                                       GST_STR_NULL(GST_ELEMENT_NAME(decodebin)));
-                       goto ERROR;
-               }
-
-               sinkpad = gst_element_get_static_pad(decodebin, "sink");
-               if (!sinkpad) {
-                       wfd_sink_error("failed to get sink pad from %s",
-                                       GST_STR_NULL(GST_ELEMENT_NAME(decodebin)));
-                       goto ERROR;
-               }
-
-               if (GST_PAD_LINK_OK != gst_pad_link(srcpad, sinkpad)) {
-                       wfd_sink_error("failed to link %s and %s",
-                                       GST_STR_NULL(GST_PAD_NAME(srcpad)),
-                                       GST_STR_NULL(GST_PAD_NAME(sinkpad)));
-                       goto ERROR;
-               }
-               gst_object_unref(GST_OBJECT(srcpad));
-               srcpad = NULL;
-               gst_object_unref(GST_OBJECT(sinkpad));
-               sinkpad = NULL;
-
-               srcpad = gst_element_get_static_pad(decodebin, "src");
-               if (!srcpad) {
-                       wfd_sink_error("failed to get src pad from %s",
-                                       GST_STR_NULL(GST_ELEMENT_NAME(decodebin)));
-                       goto ERROR;
-               }
-       } else {
-               wfd_sink_warning("going on without decodebin...");
-       }
-
-       /* add sinkbin and link */
-       if (sinkbin) {
-               if (!gst_bin_add(GST_BIN(pipeline), sinkbin)) {
-                       wfd_sink_error("failed to add %s to pipeline",
-                                       GST_STR_NULL(GST_ELEMENT_NAME(sinkbin)));
-                       goto ERROR;
-               }
-
-               sinkpad = gst_element_get_static_pad(sinkbin, "sink");
-               if (!sinkpad) {
-                       wfd_sink_error("failed to get sink pad from %s",
-                                       GST_STR_NULL(GST_ELEMENT_NAME(sinkbin)));
-                       goto ERROR;
-               }
-
-               if (GST_PAD_LINK_OK != gst_pad_link(srcpad, sinkpad)) {
-                       wfd_sink_error("failed to link %s and %s",
-                                       GST_STR_NULL(GST_PAD_NAME(srcpad)),
-                                       GST_STR_NULL(GST_PAD_NAME(sinkpad)));
-                       goto ERROR;
-               }
-               gst_object_unref(GST_OBJECT(srcpad));
-               srcpad = NULL;
-               gst_object_unref(GST_OBJECT(sinkpad));
-               sinkpad = NULL;
-       } else {
-               wfd_sink_error("there is no sinkbin...");
-               goto ERROR;
-       }
-
-
-       /* run */
-       if (decodebin) {
-               if (!gst_element_sync_state_with_parent(GST_ELEMENT_CAST(decodebin))) {
-                       wfd_sink_error("failed to sync %s state with parent",
-                               GST_STR_NULL(GST_PAD_NAME(decodebin)));
-                       goto ERROR;
-               }
-       }
-
-       if (sinkbin) {
-               if (!gst_element_sync_state_with_parent(GST_ELEMENT_CAST(sinkbin))) {
-                       wfd_sink_error("failed to sync %s state with parent",
-                               GST_STR_NULL(GST_PAD_NAME(sinkbin)));
-                       goto ERROR;
-               }
-       }
-
-       if (name[0] == 'v') {
-               MMWFDSINK_GENERATE_DOT_IF_ENABLED(wfd_sink, "video-pad-added-pipeline");
-       } else if (name[0] == 'a') {
-               MMWFDSINK_GENERATE_DOT_IF_ENABLED(wfd_sink, "audio-pad-added-pipeline");
-       }
-
-       MMWFDSINK_FREEIF(name);
-
-       wfd_sink_debug_fleave();
-
-       return;
-
-       /* ERRORS */
-ERROR:
-       MMWFDSINK_FREEIF(name);
-
-       if (srcpad)
-               gst_object_unref(GST_OBJECT(srcpad));
-       srcpad = NULL;
-
-       if (sinkpad)
-               gst_object_unref(GST_OBJECT(sinkpad));
-       sinkpad = NULL;
-
-       /* need to notify to app */
-       MMWFDSINK_POST_MESSAGE(wfd_sink,
-                                                       MM_ERROR_WFD_INTERNAL,
-                                                       MMWFDSINK_CURRENT_STATE(wfd_sink));
-
-       return;
-}
-
-static void
-__mm_wfd_sink_change_av_format(GstElement *wfdsrc, gpointer *need_to_flush, gpointer data)
-{
-       mm_wfd_sink_t *wfd_sink = (mm_wfd_sink_t *)data;
-
-       wfd_sink_debug_fenter();
-
-       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) {
-               wfd_sink_debug("need to flush pipeline");
-               *need_to_flush = (gpointer) TRUE;
-       } else {
-               wfd_sink_debug("don't need to flush pipeline");
-               *need_to_flush = (gpointer) FALSE;
-       }
-
-
-       wfd_sink_debug_fleave();
-}
-
-
-static void
-__mm_wfd_sink_update_stream_info(GstElement *wfdsrc, GstStructure *str, gpointer data)
-{
-       mm_wfd_sink_t *wfd_sink = (mm_wfd_sink_t *)data;
-       MMWFDSinkStreamInfo *stream_info = NULL;
-       gint is_valid_audio_format = FALSE;
-       gint is_valid_video_format = FALSE;
-       gint audio_codec = MM_WFD_SINK_AUDIO_CODEC_NONE;
-       gint video_codec = MM_WFD_SINK_VIDEO_CODEC_NONE;
-       gchar *audio_format;
-       gchar *video_format;
-
-       wfd_sink_debug_fenter();
-
-       wfd_sink_return_if_fail(str && GST_IS_STRUCTURE(str));
-       wfd_sink_return_if_fail(wfd_sink);
-
-       stream_info = &wfd_sink->stream_info;
-
-       audio_codec = wfd_sink->stream_info.audio_stream_info.codec;
-       video_codec = wfd_sink->stream_info.video_stream_info.codec;
-
-       if (gst_structure_has_field(str, "audio_format")) {
-               is_valid_audio_format = TRUE;
-               audio_format = g_strdup(gst_structure_get_string(str, "audio_format"));
-               if (g_strrstr(audio_format, "AAC"))
-                       stream_info->audio_stream_info.codec = MM_WFD_SINK_AUDIO_CODEC_AAC;
-               else if (g_strrstr(audio_format, "AC3"))
-                       stream_info->audio_stream_info.codec = MM_WFD_SINK_AUDIO_CODEC_AC3;
-               else if (g_strrstr(audio_format, "LPCM"))
-                       stream_info->audio_stream_info.codec = MM_WFD_SINK_AUDIO_CODEC_LPCM;
-               else {
-                       wfd_sink_error("invalid audio format(%s)...", audio_format);
-                       is_valid_audio_format = FALSE;
-               }
-
-               if (is_valid_audio_format == TRUE) {
-                       if (gst_structure_has_field(str, "audio_rate"))
-                               gst_structure_get_int(str, "audio_rate", &stream_info->audio_stream_info.sample_rate);
-                       if (gst_structure_has_field(str, "audio_channels"))
-                               gst_structure_get_int(str, "audio_channels", &stream_info->audio_stream_info.channels);
-                       if (gst_structure_has_field(str, "audio_bitwidth"))
-                               gst_structure_get_int(str, "audio_bitwidth", &stream_info->audio_stream_info.bitwidth);
-
-                       if (audio_codec != MM_WFD_SINK_AUDIO_CODEC_NONE) {
-                               if (audio_codec != stream_info->audio_stream_info.codec) {
-                                       wfd_sink_debug("audio codec is changed...need to change audio decodebin");
-                               }
-                       } else {
-                               WFD_SINK_MANAGER_APPEND_CMD(wfd_sink, WFD_SINK_MANAGER_CMD_PREPARE_A_PIPELINE);
-                       }
-
-                       wfd_sink_debug("audio_format : %s \n \t rate :  %d \n \t channels :  %d \n \t bitwidth :  %d \n \t",
-                                               audio_format,
-                                               stream_info->audio_stream_info.sample_rate,
-                                               stream_info->audio_stream_info.channels,
-                                               stream_info->audio_stream_info.bitwidth);
-               }
-       }
-
-       if (gst_structure_has_field(str, "video_format")) {
-               is_valid_video_format = TRUE;
-               video_format = g_strdup(gst_structure_get_string(str, "video_format"));
-               if (!g_strrstr(video_format, "H264")) {
-                       wfd_sink_error("invalid video format(%s)...", video_format);
-                       is_valid_video_format = FALSE;
-               }
-
-               if (is_valid_video_format == TRUE) {
-                       stream_info->video_stream_info.codec = MM_WFD_SINK_VIDEO_CODEC_H264;
-
-                       if (gst_structure_has_field(str, "video_width"))
-                               gst_structure_get_int(str, "video_width", &stream_info->video_stream_info.width);
-                       if (gst_structure_has_field(str, "video_height"))
-                               gst_structure_get_int(str, "video_height", &stream_info->video_stream_info.height);
-                       if (gst_structure_has_field(str, "video_framerate"))
-                               gst_structure_get_int(str, "video_framerate", &stream_info->video_stream_info.frame_rate);
-
-                       if (video_codec != MM_WFD_SINK_AUDIO_CODEC_NONE) {
-                               if (video_codec != stream_info->video_stream_info.codec) {
-                                       wfd_sink_debug("video codec is changed...need to change video decodebin");
-                               }
-                       } else {
-                               WFD_SINK_MANAGER_APPEND_CMD(wfd_sink, WFD_SINK_MANAGER_CMD_PREPARE_V_PIPELINE);
-                       }
-
-                       wfd_sink_debug("video_format : %s \n \t width :  %d \n \t height :  %d \n \t frame_rate :  %d \n \t",
-                                               video_format,
-                                               stream_info->video_stream_info.width,
-                                               stream_info->video_stream_info.height,
-                                               stream_info->video_stream_info.frame_rate);
-               }
-       }
-
-       WFD_SINK_MANAGER_SIGNAL_CMD(wfd_sink);
-
-       wfd_sink_debug_fleave();
-}
-
-static int __mm_wfd_sink_prepare_source(mm_wfd_sink_t *wfd_sink, GstElement *wfdsrc)
-{
-       GstStructure *audio_param = NULL;
-       GstStructure *video_param = NULL;
-       GstStructure *hdcp_param = NULL;
-       gint hdcp_version = 0;
-       gint hdcp_port = 0;
-       guint CEA_resolution = 0;
-       guint VESA_resolution = 0;
-       guint HH_resolution = 0;
-       GObjectClass *klass;
-
-       wfd_sink_debug_fenter();
-
-       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(wfdsrc, MM_ERROR_WFD_NOT_INITIALIZED);
-
-       klass = G_OBJECT_GET_CLASS(G_OBJECT(wfdsrc));
-
-       g_object_set(G_OBJECT(wfdsrc), "debug", wfd_sink->ini.set_debug_property, NULL);
-       g_object_set(G_OBJECT(wfdsrc), "enable-pad-probe", wfd_sink->ini.enable_wfdsrc_pad_probe, NULL);
-       if (g_object_class_find_property(klass, "udp-buffer-size"))
-               g_object_set(G_OBJECT(wfdsrc), "udp-buffer-size", 2097152, NULL);
-       if (g_object_class_find_property(klass, "do-request"))
-               g_object_set(G_OBJECT(wfdsrc), "do-request", wfd_sink->ini.enable_retransmission, NULL);
-       if (g_object_class_find_property(klass, "latency"))
-               g_object_set(G_OBJECT(wfdsrc), "latency", wfd_sink->ini.jitter_buffer_latency, NULL);
-
-       audio_param = gst_structure_new("audio_param",
-                                                               "audio_codec", G_TYPE_UINT, wfd_sink->ini.audio_codec,
-                                                               "audio_latency", G_TYPE_UINT, wfd_sink->ini.audio_latency,
-                                                               "audio_channels", G_TYPE_UINT, wfd_sink->ini.audio_channel,
-                                                               "audio_sampling_frequency", G_TYPE_UINT, wfd_sink->ini.audio_sampling_frequency,
-                                                               NULL);
-
-       CEA_resolution = wfd_sink->ini.video_cea_support;
-       VESA_resolution = wfd_sink->ini.video_vesa_support;
-       HH_resolution =  wfd_sink->ini.video_hh_support;
-
-       __mm_wfd_sink_prepare_video_resolution(wfd_sink->supportive_resolution, &CEA_resolution, &VESA_resolution, &HH_resolution);
-
-       wfd_sink_debug("set video resolution CEA[%x] VESA[%x] HH[%x]", CEA_resolution, VESA_resolution, HH_resolution);
-
-       video_param = gst_structure_new("video_param",
-                                                       "video_codec", G_TYPE_UINT, wfd_sink->ini.video_codec,
-                                                       "video_native_resolution", G_TYPE_UINT, wfd_sink->ini.video_native_resolution,
-                                                       "video_cea_support", G_TYPE_UINT, CEA_resolution,
-                                                       "video_vesa_support", G_TYPE_UINT, VESA_resolution,
-                                                       "video_hh_support", G_TYPE_UINT, HH_resolution,
-                                                       "video_profile", G_TYPE_UINT, wfd_sink->ini.video_profile,
-                                                       "video_level", G_TYPE_UINT, wfd_sink->ini.video_level,
-                                                       "video_latency", G_TYPE_UINT, wfd_sink->ini.video_latency,
-                                                       "video_vertical_resolution", G_TYPE_INT, wfd_sink->ini.video_vertical_resolution,
-                                                       "video_horizontal_resolution", G_TYPE_INT, wfd_sink->ini.video_horizontal_resolution,
-                                                       "video_minimum_slicing", G_TYPE_INT, wfd_sink->ini.video_minimum_slicing,
-                                                       "video_slice_enc_param", G_TYPE_INT, wfd_sink->ini.video_slice_enc_param,
-                                                       "video_framerate_control_support", G_TYPE_INT, wfd_sink->ini.video_framerate_control_support,
-                                                       NULL);
-
-       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);
-       wfd_sink_debug("set hdcp version %d with %d port", hdcp_version, hdcp_port);
-
-       hdcp_param = gst_structure_new("hdcp_param",
-                                                       "hdcp_version", G_TYPE_INT, hdcp_version,
-                                                       "hdcp_port_no", G_TYPE_INT, hdcp_port,
-                                                       NULL);
-
-       g_object_set(G_OBJECT(wfdsrc), "audio-param", audio_param, NULL);
-       g_object_set(G_OBJECT(wfdsrc), "video-param", video_param, NULL);
-       g_object_set(G_OBJECT(wfdsrc), "hdcp-param", hdcp_param, NULL);
-
-       g_signal_connect(wfdsrc, "update-media-info", G_CALLBACK(__mm_wfd_sink_update_stream_info), wfd_sink);
-
-       g_signal_connect(wfdsrc, "change-av-format", G_CALLBACK(__mm_wfd_sink_change_av_format), wfd_sink);
-
-       wfd_sink_debug_fleave();
-
-       return MM_ERROR_NONE;
-}
-
-static int __mm_wfd_sink_prepare_demux(mm_wfd_sink_t *wfd_sink, GstElement *demux)
-{
-       wfd_sink_debug_fenter();
-
-       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);
-
-       wfd_sink_debug_fleave();
-
-       return MM_ERROR_NONE;
-}
-
-static void __mm_wfd_sink_queue_overrun(GstElement *element, gpointer u_data)
-{
-       wfd_sink_debug_fenter();
-
-       return_if_fail(element);
-
-       wfd_sink_warning("%s is overrun",
-                                       GST_STR_NULL(GST_ELEMENT_NAME(element)));
-
-       wfd_sink_debug_fleave();
-
-       return;
-}
-
-static void __mm_wfd_sink_prepare_queue(mm_wfd_sink_t *wfd_sink, GstElement *queue)
-{
-       wfd_sink_debug_fenter();
-
-       wfd_sink_return_if_fail(wfd_sink);
-       wfd_sink_return_if_fail(queue);
-
-       /* set maximum buffer size of queue as 3sec */
-       g_object_set(G_OBJECT(queue), "max-size-bytes", 0, NULL);
-       g_object_set(G_OBJECT(queue), "max-size-buffers", 0, NULL);
-       g_object_set(G_OBJECT(queue), "max-size-time", (guint64)3000000000ULL, NULL);
-       g_signal_connect(queue, "overrun", G_CALLBACK(__mm_wfd_sink_queue_overrun), wfd_sink);
-
-       wfd_sink_debug_fleave();
-
-       return;
-}
-
-
-static int __mm_wfd_sink_create_pipeline(mm_wfd_sink_t *wfd_sink)
-{
-       MMWFDSinkGstElement *mainbin = NULL;
-       GList *element_bucket = NULL;
-       GstBus  *bus = NULL;
-       int i;
-
-       wfd_sink_debug_fenter();
-
-       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));
-       if (wfd_sink->pipeline == NULL)
-               goto CREATE_ERROR;
-
-       memset(wfd_sink->pipeline, 0, sizeof(MMWFDSinkGstPipelineInfo));
-
-       /* create mainbin */
-       mainbin = (MMWFDSinkGstElement *) g_malloc0(sizeof(MMWFDSinkGstElement) * WFD_SINK_M_NUM);
-       if (mainbin == NULL)
-               goto CREATE_ERROR;
-
-       memset(mainbin, 0, sizeof(MMWFDSinkGstElement) * WFD_SINK_M_NUM);
-
-       /* create pipeline */
-       mainbin[WFD_SINK_M_PIPE].id = WFD_SINK_M_PIPE;
-       mainbin[WFD_SINK_M_PIPE].gst = gst_pipeline_new("wfdsink");
-       if (!mainbin[WFD_SINK_M_PIPE].gst) {
-               wfd_sink_error("failed to create pipeline");
-               goto CREATE_ERROR;
-       }
-
-       /* create wfdsrc */
-       MMWFDSINK_CREATE_ELEMENT(mainbin, WFD_SINK_M_SRC, wfd_sink->ini.name_of_source, "wfdsink_source", TRUE);
-       MMWFDSINK_PAD_PROBE(wfd_sink, NULL, mainbin[WFD_SINK_M_SRC].gst,  "src");
-       if (mainbin[WFD_SINK_M_SRC].gst) {
-               if (MM_ERROR_NONE != __mm_wfd_sink_prepare_source(wfd_sink, mainbin[WFD_SINK_M_SRC].gst)) {
-                       wfd_sink_error("failed to prepare wfdsrc...");
-                       goto CREATE_ERROR;
-               }
-       }
-
-       /* create rtpmp2tdepay */
-       MMWFDSINK_CREATE_ELEMENT(mainbin, WFD_SINK_M_DEPAY, "rtpmp2tdepay", "wfdsink_depay", TRUE);
-       MMWFDSINK_PAD_PROBE(wfd_sink, NULL, mainbin[WFD_SINK_M_DEPAY].gst, "src");
-       MMWFDSINK_PAD_PROBE(wfd_sink, NULL, mainbin[WFD_SINK_M_DEPAY].gst, "sink");
-
-       MMWFDSINK_TS_DATA_DUMP(wfd_sink, mainbin[WFD_SINK_M_DEPAY].gst, "src");
-
-       /* 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 (mainbin[WFD_SINK_M_DEMUX].gst) {
-               if (MM_ERROR_NONE != __mm_wfd_sink_prepare_demux(wfd_sink, mainbin[WFD_SINK_M_DEMUX].gst)) {
-                       wfd_sink_error("failed to prepare demux...");
-                       goto CREATE_ERROR;
-               }
-       }
-
-       /* adding created elements to pipeline */
-       if (!__mm_wfd_sink_gst_element_add_bucket_to_bin(GST_BIN_CAST(mainbin[WFD_SINK_M_PIPE].gst), element_bucket, FALSE)) {
-               wfd_sink_error("failed to add elements");
-               goto CREATE_ERROR;
-       }
-
-       /* linking elements in the bucket by added order. */
-       if (__mm_wfd_sink_gst_element_link_bucket(element_bucket) == -1) {
-               wfd_sink_error("failed to link elements");
-               goto CREATE_ERROR;
-       }
-
-       /* connect bus callback */
-       bus = gst_pipeline_get_bus(GST_PIPELINE(mainbin[WFD_SINK_M_PIPE].gst));
-       if (!bus) {
-               wfd_sink_error("cannot get bus from pipeline.");
-               goto CREATE_ERROR;
-       }
-
-       /* add bus message callback*/
-       gst_bus_add_watch(bus, (GstBusFunc)_mm_wfd_sink_msg_callback, wfd_sink);
-
-       /* set sync handler to get tag synchronously */
-       gst_bus_set_sync_handler(bus, _mm_wfd_bus_sync_callback, wfd_sink, NULL);
-
-       g_list_free(element_bucket);
-       gst_object_unref(GST_OBJECT(bus));
-
-       /* now we have completed mainbin. take it */
-       wfd_sink->pipeline->mainbin = mainbin;
-
-       wfd_sink_debug_fleave();
-
-       return MM_ERROR_NONE;
-
-       /* ERRORS */
-CREATE_ERROR:
-       wfd_sink_error("ERROR : releasing pipeline");
-
-       if (element_bucket)
-               g_list_free(element_bucket);
-       element_bucket = NULL;
-
-       /* finished */
-       if (bus)
-               gst_object_unref(GST_OBJECT(bus));
-       bus = NULL;
-
-       /* release element which are not added to bin */
-       for (i = 1; i < WFD_SINK_M_NUM; i++) {  /* NOTE : skip pipeline */
-               if (mainbin != NULL && mainbin[i].gst) {
-                       GstObject *parent = NULL;
-                       parent = gst_element_get_parent(mainbin[i].gst);
-
-                       if (!parent) {
-                               gst_object_unref(GST_OBJECT(mainbin[i].gst));
-                               mainbin[i].gst = NULL;
-                       } else {
-                               gst_object_unref(GST_OBJECT(parent));
-                       }
-               }
-       }
-
-       /* release mainbin with it's childs */
-       if (mainbin != NULL && mainbin[WFD_SINK_M_PIPE].gst)
-               gst_object_unref(GST_OBJECT(mainbin[WFD_SINK_M_PIPE].gst));
-
-       MMWFDSINK_FREEIF(mainbin);
-
-       MMWFDSINK_FREEIF(wfd_sink->pipeline);
-
-       return MM_ERROR_WFD_INTERNAL;
-}
-
-int __mm_wfd_sink_link_audio_decodebin(mm_wfd_sink_t *wfd_sink)
-{
-       MMWFDSinkGstElement *a_decodebin = NULL;
-       MMWFDSinkGstElement *first_element = NULL;
-       MMWFDSinkGstElement *last_element = NULL;
-       GList *element_bucket = NULL;
-       GstPad *sinkpad = NULL;
-       GstPad *srcpad = NULL;
-       GstPad *ghostpad = NULL;
-       GList *first_list = NULL;
-       GList *last_list = NULL;
-
-       wfd_sink_debug_fenter();
-
-       wfd_sink_return_val_if_fail(wfd_sink &&
-                                               wfd_sink->pipeline &&
-                                               wfd_sink->pipeline->a_decodebin &&
-                                               wfd_sink->pipeline->a_decodebin[WFD_SINK_A_D_BIN].gst,
-                                               MM_ERROR_WFD_NOT_INITIALIZED);
-
-       if (wfd_sink->audio_decodebin_is_linked) {
-               wfd_sink_debug("audio decodebin is already linked... nothing to do");
-               return MM_ERROR_NONE;
-       }
-
-       /* take audio decodebin */
-       a_decodebin = wfd_sink->pipeline->a_decodebin;
-
-       /* check audio queue */
-       if (a_decodebin[WFD_SINK_A_D_QUEUE].gst)
-               element_bucket = g_list_append(element_bucket, &a_decodebin[WFD_SINK_A_D_QUEUE]);
-
-       /* check audio hdcp */
-       if (a_decodebin[WFD_SINK_A_D_HDCP].gst)
-               element_bucket = g_list_append(element_bucket, &a_decodebin[WFD_SINK_A_D_HDCP]);
-
-       /* check audio codec */
-       switch (wfd_sink->stream_info.audio_stream_info.codec) {
-               case MM_WFD_SINK_AUDIO_CODEC_LPCM:
-                       if (a_decodebin[WFD_SINK_A_D_LPCM_CONVERTER].gst)
-                               element_bucket = g_list_append(element_bucket, &a_decodebin[WFD_SINK_A_D_LPCM_CONVERTER]);
-                       if (a_decodebin[WFD_SINK_A_D_LPCM_FILTER].gst) {
-                               GstCaps *caps = NULL;
-                               element_bucket = g_list_append(element_bucket, &a_decodebin[WFD_SINK_A_D_LPCM_FILTER]);
-                               caps = gst_caps_new_simple("audio/x-raw",
-                                                                       "rate", G_TYPE_INT, wfd_sink->stream_info.audio_stream_info.sample_rate,
-                                                                       "channels", G_TYPE_INT, wfd_sink->stream_info.audio_stream_info.channels,
-                                                                       "format", G_TYPE_STRING, "S16BE", NULL);
-
-                               g_object_set(G_OBJECT(a_decodebin[WFD_SINK_A_D_LPCM_CONVERTER].gst), "caps", caps, NULL);
-                               gst_object_unref(GST_OBJECT(caps));
-                       }
-                       break;
-
-               case MM_WFD_SINK_AUDIO_CODEC_AAC:
-                       if (a_decodebin[WFD_SINK_A_D_AAC_PARSE].gst)
-                               element_bucket = g_list_append(element_bucket, &a_decodebin[WFD_SINK_A_D_AAC_PARSE]);
-                       if (a_decodebin[WFD_SINK_A_D_AAC_DEC].gst)
-                               element_bucket = g_list_append(element_bucket, &a_decodebin[WFD_SINK_A_D_AAC_DEC]);
-                       break;
-
-               case MM_WFD_SINK_AUDIO_CODEC_AC3:
-                       if (a_decodebin[WFD_SINK_A_D_AC3_PARSE].gst)
-                               element_bucket = g_list_append(element_bucket, &a_decodebin[WFD_SINK_A_D_AC3_PARSE]);
-                       if (a_decodebin[WFD_SINK_A_D_AC3_DEC].gst)
-                               element_bucket = g_list_append(element_bucket, &a_decodebin[WFD_SINK_A_D_AC3_DEC]);
-                       break;
-
-               default:
-                       wfd_sink_error("audio codec is not decied yet. cannot link audio decodebin...");
-                       return MM_ERROR_WFD_INTERNAL;
-                       break;
-       }
-
-       if (element_bucket == NULL) {
-               wfd_sink_error("there are no elements to be linked in the audio decodebin, destroy it");
-               if (MM_ERROR_NONE != __mm_wfd_sink_destroy_audio_decodebin(wfd_sink)) {
-                       wfd_sink_error("failed to destroy audio decodebin");
-                       goto fail_to_link;
-               }
-               goto done;
-       }
-
-       /* adding elements to audio decodebin */
-       if (!__mm_wfd_sink_gst_element_add_bucket_to_bin(GST_BIN_CAST(a_decodebin[WFD_SINK_A_D_BIN].gst), element_bucket, FALSE)) {
-               wfd_sink_error("failed to add elements to audio decodebin");
-               goto fail_to_link;
-       }
-
-       /* linking elements in the bucket by added order. */
-       if (__mm_wfd_sink_gst_element_link_bucket(element_bucket) == -1) {
-               wfd_sink_error("failed to link elements of the audio decodebin");
-               goto fail_to_link;
-       }
-
-       /* get first element's sinkpad for creating ghostpad */
-       first_list = g_list_first(element_bucket);
-       if (first_list == NULL) {
-               wfd_sink_error("failed to get first list of the element_bucket");
-               goto fail_to_link;
-       }
-
-       first_element = (MMWFDSinkGstElement *)first_list->data;
-       if (!first_element) {
-               wfd_sink_error("failed to get first element of the audio decodebin");
-               goto fail_to_link;
-       }
-
-       sinkpad = gst_element_get_static_pad(GST_ELEMENT(first_element->gst), "sink");
-       if (!sinkpad) {
-               wfd_sink_error("failed to get sink pad from element(%s)",
-                       GST_STR_NULL(GST_ELEMENT_NAME(first_element->gst)));
-               goto fail_to_link;
-       }
-
-       ghostpad = gst_ghost_pad_new("sink", sinkpad);
-       if (!ghostpad) {
-               wfd_sink_error("failed to create ghostpad of audio decodebin");
-               goto fail_to_link;
-       }
-
-       if (FALSE == gst_element_add_pad(a_decodebin[WFD_SINK_A_D_BIN].gst, ghostpad)) {
-               wfd_sink_error("failed to add ghostpad to audio decodebin");
-               goto fail_to_link;
-       }
-       gst_object_unref(GST_OBJECT(sinkpad));
-       sinkpad = NULL;
-
-
-       /* get last element's src for creating ghostpad */
-       last_list = g_list_last(element_bucket);
-       if (last_list == NULL) {
-               wfd_sink_error("failed to get last list of the element_bucket");
-               goto fail_to_link;
-       }
-
-       last_element = (MMWFDSinkGstElement *)last_list->data;
-       if (!last_element) {
-               wfd_sink_error("failed to get last element of the audio decodebin");
-               goto fail_to_link;
-       }
-
-       srcpad = gst_element_get_static_pad(GST_ELEMENT(last_element->gst), "src");
-       if (!srcpad) {
-               wfd_sink_error("failed to get src pad from element(%s)",
-                       GST_STR_NULL(GST_ELEMENT_NAME(last_element->gst)));
-               goto fail_to_link;
-       }
-
-       ghostpad = gst_ghost_pad_new("src", srcpad);
-       if (!ghostpad) {
-               wfd_sink_error("failed to create ghostpad of audio decodebin");
-               goto fail_to_link;
-       }
-
-       if (FALSE == gst_element_add_pad(a_decodebin[WFD_SINK_A_D_BIN].gst, ghostpad)) {
-               wfd_sink_error("failed to add ghostpad to audio decodebin");
-               goto fail_to_link;
-       }
-       gst_object_unref(GST_OBJECT(srcpad));
-       srcpad = NULL;
-
-       g_list_free(element_bucket);
-
-done:
-       wfd_sink->audio_decodebin_is_linked = TRUE;
-
-       wfd_sink_debug_fleave();
-
-       return MM_ERROR_NONE;
-
-       /* ERRORS*/
-fail_to_link:
-       if (srcpad)
-               gst_object_unref(GST_OBJECT(srcpad));
-       srcpad = NULL;
-
-       if (sinkpad)
-               gst_object_unref(GST_OBJECT(sinkpad));
-       sinkpad = NULL;
-
-       g_list_free(element_bucket);
-
-       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), "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 int  __mm_wfd_sink_destroy_audio_decodebin(mm_wfd_sink_t *wfd_sink)
-{
-       GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
-       MMWFDSinkGstElement *a_decodebin = 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->a_decodebin &&
-           wfd_sink->pipeline->a_decodebin[WFD_SINK_A_D_BIN].gst) {
-               a_decodebin = wfd_sink->pipeline->a_decodebin;
-       } else {
-               wfd_sink_debug("audio decodebin is not created, nothing to destroy");
-               return MM_ERROR_NONE;
-       }
-
-       parent = gst_element_get_parent(a_decodebin[WFD_SINK_A_D_BIN].gst);
-       if (!parent) {
-               wfd_sink_debug("audio decodebin has no parent.. need to relase by itself");
-
-               if (GST_STATE(a_decodebin[WFD_SINK_A_D_BIN].gst) >= GST_STATE_READY) {
-                       wfd_sink_debug("try to change state of audio decodebin to NULL");
-                       ret = gst_element_set_state(a_decodebin[WFD_SINK_A_D_BIN].gst, GST_STATE_NULL);
-                       if (ret != GST_STATE_CHANGE_SUCCESS) {
-                               wfd_sink_error("failed to change state of audio decodebin to NULL");
-                               return MM_ERROR_WFD_INTERNAL;
-                       }
-               }
-
-               /* release element which are not added to bin */
-               for (i = 1; i < WFD_SINK_A_D_NUM; i++) {        /* NOTE : skip bin */
-                       if (a_decodebin[i].gst) {
-                               parent = gst_element_get_parent(a_decodebin[i].gst);
-                               if (!parent) {
-                                       wfd_sink_debug("unref %s(current ref %d)",
-                                                       GST_STR_NULL(GST_ELEMENT_NAME(a_decodebin[i].gst)),
-                                                       ((GObject *) a_decodebin[i].gst)->ref_count);
-                                       gst_object_unref(GST_OBJECT(a_decodebin[i].gst));
-                                       a_decodebin[i].gst = NULL;
-                               } else {
-                                       wfd_sink_debug("unref %s(current ref %d)",
-                                                       GST_STR_NULL(GST_ELEMENT_NAME(a_decodebin[i].gst)),
-                                                       ((GObject *) a_decodebin[i].gst)->ref_count);
-                                       gst_object_unref(GST_OBJECT(parent));
-                               }
-                       }
-               }
-
-               /* release audio decodebin with it's childs */
-               if (a_decodebin[WFD_SINK_A_D_BIN].gst)
-                       gst_object_unref(GST_OBJECT(a_decodebin[WFD_SINK_A_D_BIN].gst));
-
-       } else {
-               wfd_sink_debug("audio decodebin has parent(%s), unref it ",
-                                       GST_STR_NULL(GST_OBJECT_NAME(GST_OBJECT(parent))));
-
-               gst_object_unref(GST_OBJECT(parent));
-       }
-
-       wfd_sink->audio_decodebin_is_linked = FALSE;
-
-       MMWFDSINK_FREEIF(wfd_sink->pipeline->a_decodebin);
-
-       wfd_sink_debug_fleave();
-
-       return MM_ERROR_NONE;
-}
-
-static int __mm_wfd_sink_create_audio_decodebin(mm_wfd_sink_t *wfd_sink)
-{
-       MMWFDSinkGstElement *a_decodebin = NULL;
-       gint audio_codec = WFD_AUDIO_UNKNOWN;
-       GList *element_bucket = NULL;
-       gboolean link = TRUE;
-       gint i = 0;
-
-       wfd_sink_debug_fenter();
-
-       wfd_sink_return_val_if_fail(wfd_sink &&
-                                               wfd_sink->pipeline,
-                                               MM_ERROR_WFD_NOT_INITIALIZED);
-
-       /* check audio decodebin could be linked now */
-       switch (wfd_sink->stream_info.audio_stream_info.codec) {
-               case MM_WFD_SINK_AUDIO_CODEC_AAC:
-                       audio_codec = WFD_AUDIO_AAC;
-                       link = TRUE;
-                       break;
-               case MM_WFD_SINK_AUDIO_CODEC_AC3:
-                       audio_codec = WFD_AUDIO_AC3;
-                       link = TRUE;
-                       break;
-               case MM_WFD_SINK_AUDIO_CODEC_LPCM:
-                       audio_codec = WFD_AUDIO_LPCM;
-                       link = TRUE;
-                       break;
-               case MM_WFD_SINK_AUDIO_CODEC_NONE:
-               default:
-                       wfd_sink_debug("audio decodebin could NOT be linked now, just create");
-                       audio_codec = wfd_sink->ini.audio_codec;
-                       link = FALSE;
-                       break;
-       }
-
-       /* alloc handles */
-       a_decodebin = (MMWFDSinkGstElement *)g_malloc0(sizeof(MMWFDSinkGstElement) * WFD_SINK_A_D_NUM);
-       if (!a_decodebin) {
-               wfd_sink_error("failed to allocate memory for audio decodebin");
-               return MM_ERROR_WFD_NO_FREE_SPACE;
-       }
-
-       memset(a_decodebin, 0, sizeof(MMWFDSinkGstElement) * WFD_SINK_A_D_NUM);
-
-       /* create audio decodebin */
-       a_decodebin[WFD_SINK_A_D_BIN].id = WFD_SINK_A_D_BIN;
-       a_decodebin[WFD_SINK_A_D_BIN].gst = gst_bin_new("audio_deocebin");
-       if (!a_decodebin[WFD_SINK_A_D_BIN].gst) {
-               wfd_sink_error("failed to create audio decodebin");
-               goto CREATE_ERROR;
-       }
-
-       /* create queue */
-       MMWFDSINK_CREATE_ELEMENT(a_decodebin, WFD_SINK_A_D_QUEUE, "queue", "audio_queue", FALSE);
-       MMWFDSINK_PAD_PROBE(wfd_sink, NULL, a_decodebin[WFD_SINK_A_D_QUEUE].gst,  "sink");
-       if (a_decodebin[WFD_SINK_A_D_QUEUE].gst)
-               __mm_wfd_sink_prepare_queue(wfd_sink, a_decodebin[WFD_SINK_A_D_QUEUE].gst);
-
-       /* create hdcp */
-       MMWFDSINK_CREATE_ELEMENT(a_decodebin, WFD_SINK_A_D_HDCP, wfd_sink->ini.name_of_audio_hdcp, "audio_hdcp", FALSE);
-       MMWFDSINK_PAD_PROBE(wfd_sink, NULL, a_decodebin[WFD_SINK_A_D_HDCP].gst,  "sink");
-
-       /* create codec */
-       audio_codec = wfd_sink->ini.audio_codec;
-       if (audio_codec & WFD_AUDIO_LPCM) {
-               /* create LPCM converter */
-               MMWFDSINK_CREATE_ELEMENT(a_decodebin, WFD_SINK_A_D_LPCM_CONVERTER, wfd_sink->ini.name_of_lpcm_converter, "audio_lpcm_convert", FALSE);
-               MMWFDSINK_PAD_PROBE(wfd_sink, NULL, a_decodebin[WFD_SINK_A_D_LPCM_CONVERTER].gst,  "sink");
-               MMWFDSINK_PAD_PROBE(wfd_sink, NULL, a_decodebin[WFD_SINK_A_D_LPCM_CONVERTER].gst,  "src");
-
-               /* create LPCM filter */
-               MMWFDSINK_CREATE_ELEMENT(a_decodebin, WFD_SINK_A_D_LPCM_FILTER, wfd_sink->ini.name_of_lpcm_filter, "audio_lpcm_filter", FALSE);
-               MMWFDSINK_PAD_PROBE(wfd_sink, NULL, a_decodebin[WFD_SINK_A_D_LPCM_FILTER].gst,  "sink");
-               MMWFDSINK_PAD_PROBE(wfd_sink, NULL, a_decodebin[WFD_SINK_A_D_LPCM_FILTER].gst,  "src");
-       }
-
-       if (audio_codec & WFD_AUDIO_AAC) {
-               /* create AAC parse  */
-               MMWFDSINK_CREATE_ELEMENT(a_decodebin, WFD_SINK_A_D_AAC_PARSE, wfd_sink->ini.name_of_aac_parser, "audio_aac_parser", FALSE);
-               MMWFDSINK_PAD_PROBE(wfd_sink, NULL, a_decodebin[WFD_SINK_A_D_AAC_PARSE].gst,  "sink");
-               MMWFDSINK_PAD_PROBE(wfd_sink, NULL, a_decodebin[WFD_SINK_A_D_AAC_PARSE].gst,  "src");
-
-               /* create AAC decoder  */
-               MMWFDSINK_CREATE_ELEMENT(a_decodebin, WFD_SINK_A_D_AAC_DEC, wfd_sink->ini.name_of_aac_decoder, "audio_aac_dec", FALSE);
-               MMWFDSINK_PAD_PROBE(wfd_sink, NULL, a_decodebin[WFD_SINK_A_D_AAC_DEC].gst,  "sink");
-               MMWFDSINK_PAD_PROBE(wfd_sink, NULL, a_decodebin[WFD_SINK_A_D_AAC_DEC].gst,  "src");
-       }
-
-       if (audio_codec & WFD_AUDIO_AC3) {
-               /* create AC3 parser  */
-               MMWFDSINK_CREATE_ELEMENT(a_decodebin, WFD_SINK_A_D_AC3_PARSE, wfd_sink->ini.name_of_ac3_parser, "audio_ac3_parser", FALSE);
-               MMWFDSINK_PAD_PROBE(wfd_sink, NULL, a_decodebin[WFD_SINK_A_D_AC3_PARSE].gst,  "sink");
-               MMWFDSINK_PAD_PROBE(wfd_sink, NULL, a_decodebin[WFD_SINK_A_D_AC3_PARSE].gst,  "src");
-
-               /* create AC3 decoder  */
-               MMWFDSINK_CREATE_ELEMENT(a_decodebin, WFD_SINK_A_D_AC3_DEC, wfd_sink->ini.name_of_ac3_decoder, "audio_ac3_dec", FALSE);
-               MMWFDSINK_PAD_PROBE(wfd_sink, NULL, a_decodebin[WFD_SINK_A_D_AC3_DEC].gst,  "sink");
-               MMWFDSINK_PAD_PROBE(wfd_sink, NULL, a_decodebin[WFD_SINK_A_D_AC3_DEC].gst,  "src");
-       }
-
-       g_list_free(element_bucket);
-
-       /* take it */
-       wfd_sink->pipeline->a_decodebin = a_decodebin;
-
-       /* link audio decodebin if audio codec is fixed */
-       if (link) {
-               if (MM_ERROR_NONE != __mm_wfd_sink_link_audio_decodebin(wfd_sink)) {
-                       wfd_sink_error("failed to link audio decodebin, destroy audio decodebin");
-                       __mm_wfd_sink_destroy_audio_decodebin(wfd_sink);
-                       return MM_ERROR_WFD_INTERNAL;
-               }
-       }
-
-       wfd_sink_debug_fleave();
-
-       return MM_ERROR_NONE;
-
-CREATE_ERROR:
-       wfd_sink_error("failed to create audio decodebin, release all");
-
-       g_list_free(element_bucket);
-
-       /* release element which are not added to bin */
-       for (i = 1; i < WFD_SINK_A_D_NUM; i++) {        /* NOTE : skip bin */
-               if (a_decodebin != NULL && a_decodebin[i].gst) {
-                       GstObject *parent = NULL;
-                       parent = gst_element_get_parent(a_decodebin[i].gst);
-
-                       if (!parent) {
-                               gst_object_unref(GST_OBJECT(a_decodebin[i].gst));
-                               a_decodebin[i].gst = NULL;
-                       } else {
-                               gst_object_unref(GST_OBJECT(parent));
-                       }
-               }
-       }
-
-       /* release audioo decodebin with it's childs */
-       if (a_decodebin != NULL && a_decodebin[WFD_SINK_A_D_BIN].gst)
-               gst_object_unref(GST_OBJECT(a_decodebin[WFD_SINK_A_D_BIN].gst));
-
-       MMWFDSINK_FREEIF(a_decodebin);
-
-       return MM_ERROR_WFD_INTERNAL;
-}
-
-static int  __mm_wfd_sink_destroy_audio_sinkbin(mm_wfd_sink_t *wfd_sink)
-{
-       GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
-       MMWFDSinkGstElement *a_sinkbin = 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->a_sinkbin &&
-           wfd_sink->pipeline->a_sinkbin[WFD_SINK_A_S_BIN].gst) {
-               a_sinkbin = wfd_sink->pipeline->a_sinkbin;
-       } else {
-               wfd_sink_debug("audio sinkbin is not created, nothing to destroy");
-               return MM_ERROR_NONE;
-       }
-
-       parent = gst_element_get_parent(a_sinkbin[WFD_SINK_A_S_BIN].gst);
-       if (!parent) {
-               wfd_sink_debug("audio decodebin has no parent.. need to relase by itself");
-
-               if (GST_STATE(a_sinkbin[WFD_SINK_A_S_BIN].gst) >= GST_STATE_READY) {
-                       wfd_sink_debug("try to change state of audio decodebin to NULL");
-                       ret = gst_element_set_state(a_sinkbin[WFD_SINK_A_S_BIN].gst, GST_STATE_NULL);
-                       if (ret != GST_STATE_CHANGE_SUCCESS) {
-                               wfd_sink_error("failed to change state of audio decodebin to NULL");
-                               return MM_ERROR_WFD_INTERNAL;
-                       }
-               }
-
-               /* release element which are not added to bin */
-               for (i = 1; i < WFD_SINK_A_S_NUM; i++) {        /* NOTE : skip bin */
-                       if (a_sinkbin[i].gst) {
-                               parent = gst_element_get_parent(a_sinkbin[i].gst);
-                               if (!parent) {
-                                       wfd_sink_debug("unref %s(current ref %d)",
-                                                       GST_STR_NULL(GST_ELEMENT_NAME(a_sinkbin[i].gst)),
-                                                       ((GObject *) a_sinkbin[i].gst)->ref_count);
-                                       gst_object_unref(GST_OBJECT(a_sinkbin[i].gst));
-                                       a_sinkbin[i].gst = NULL;
-                               } else {
-                                       wfd_sink_debug("unref %s(current ref %d)",
-                                                       GST_STR_NULL(GST_ELEMENT_NAME(a_sinkbin[i].gst)),
-                                                       ((GObject *) a_sinkbin[i].gst)->ref_count);
-                                       gst_object_unref(GST_OBJECT(parent));
-                               }
-                       }
-               }
-
-               /* release audio decodebin with it's childs */
-               if (a_sinkbin[WFD_SINK_A_S_BIN].gst)
-                       gst_object_unref(GST_OBJECT(a_sinkbin[WFD_SINK_A_S_BIN].gst));
-
-       } else {
-               wfd_sink_debug("audio sinkbin has parent(%s), unref it ",
-                                       GST_STR_NULL(GST_OBJECT_NAME(GST_OBJECT(parent))));
-
-               gst_object_unref(GST_OBJECT(parent));
-       }
-
-       MMWFDSINK_FREEIF(wfd_sink->pipeline->a_sinkbin);
-
-       wfd_sink_debug_fleave();
-
-       return MM_ERROR_NONE;
-}
-
-static int __mm_wfd_sink_create_audio_sinkbin(mm_wfd_sink_t *wfd_sink)
-{
-       MMWFDSinkGstElement *a_sinkbin = NULL;
-       MMWFDSinkGstElement *first_element = NULL;
-       GList *element_bucket = NULL;
-       GstPad *ghostpad = NULL;
-       GstPad *pad = NULL;
-       gint i = 0;
-       GList *first_list = NULL;
-
-       wfd_sink_debug_fenter();
-
-       wfd_sink_return_val_if_fail(wfd_sink &&
-                                               wfd_sink->pipeline,
-                                               MM_ERROR_WFD_NOT_INITIALIZED);
-
-       /* alloc handles */
-       a_sinkbin = (MMWFDSinkGstElement *)g_malloc0(sizeof(MMWFDSinkGstElement) * WFD_SINK_A_S_NUM);
-       if (!a_sinkbin) {
-               wfd_sink_error("failed to allocate memory for audio sinkbin");
-               return MM_ERROR_WFD_NO_FREE_SPACE;
-       }
-
-       memset(a_sinkbin, 0, sizeof(MMWFDSinkGstElement) * WFD_SINK_A_S_NUM);
-
-       /* create audio sinkbin */
-       a_sinkbin[WFD_SINK_A_S_BIN].id = WFD_SINK_A_S_BIN;
-       a_sinkbin[WFD_SINK_A_S_BIN].gst = gst_bin_new("audio_sinkbin");
-       if (!a_sinkbin[WFD_SINK_A_S_BIN].gst) {
-               wfd_sink_error("failed to create audio sinkbin");
-               goto CREATE_ERROR;
-       }
-
-       /* create resampler */
-       MMWFDSINK_CREATE_ELEMENT(a_sinkbin, WFD_SINK_A_S_RESAMPLER, wfd_sink->ini.name_of_audio_resampler, "audio_resampler", TRUE);
-       MMWFDSINK_PAD_PROBE(wfd_sink, NULL, a_sinkbin[WFD_SINK_A_S_RESAMPLER].gst,  "sink");
-       MMWFDSINK_PAD_PROBE(wfd_sink, NULL, a_sinkbin[WFD_SINK_A_S_RESAMPLER].gst,  "src");
-
-       /* create volume */
-       MMWFDSINK_CREATE_ELEMENT(a_sinkbin, WFD_SINK_A_S_VOLUME, wfd_sink->ini.name_of_audio_volume, "audio_volume", TRUE);
-       MMWFDSINK_PAD_PROBE(wfd_sink, NULL, a_sinkbin[WFD_SINK_A_S_VOLUME].gst,  "sink");
-       MMWFDSINK_PAD_PROBE(wfd_sink, NULL, a_sinkbin[WFD_SINK_A_S_VOLUME].gst,  "src");
-
-       /* create sink */
-       MMWFDSINK_CREATE_ELEMENT(a_sinkbin, WFD_SINK_A_S_SINK, wfd_sink->ini.name_of_audio_sink, "audio_sink", TRUE);
-       MMWFDSINK_PAD_PROBE(wfd_sink, NULL, a_sinkbin[WFD_SINK_A_S_SINK].gst,  "sink");
-       if (a_sinkbin[WFD_SINK_A_S_SINK].gst) {
-               if (MM_ERROR_NONE != __mm_wfd_sink_prepare_audiosink(wfd_sink, a_sinkbin[WFD_SINK_A_S_SINK].gst)) {
-                       wfd_sink_error("failed to set audio sink property....");
-                       goto CREATE_ERROR;
-               }
-       }
-
-       /* adding created elements to audio sinkbin */
-       if (!__mm_wfd_sink_gst_element_add_bucket_to_bin(GST_BIN_CAST(a_sinkbin[WFD_SINK_A_S_BIN].gst), element_bucket, FALSE)) {
-               wfd_sink_error("failed to add elements to audio sinkbin");
-               goto CREATE_ERROR;
-       }
-
-       /* linking elements in the bucket by added order. */
-       if (__mm_wfd_sink_gst_element_link_bucket(element_bucket) == -1) {
-               wfd_sink_error("failed to link elements fo the audio sinkbin");
-               goto CREATE_ERROR;
-       }
-
-       /* get first element's of the audio sinkbin */
-       first_list = g_list_first(element_bucket);
-       if (first_list == NULL) {
-               wfd_sink_error("failed to get first list of the element_bucket");
-               goto CREATE_ERROR;
-       }
-
-       first_element = (MMWFDSinkGstElement *)first_list->data;
-       if (!first_element) {
-               wfd_sink_error("failed to get first element of the audio sinkbin");
-               goto CREATE_ERROR;
-       }
-
-       /* get first element's sinkpad for creating ghostpad */
-       pad = gst_element_get_static_pad(GST_ELEMENT(first_element->gst), "sink");
-       if (!pad) {
-               wfd_sink_error("failed to get sink pad from element(%s)",
-                       GST_STR_NULL(GST_ELEMENT_NAME(first_element->gst)));
-               goto CREATE_ERROR;
-       }
-
-       ghostpad = gst_ghost_pad_new("sink", pad);
-       if (!ghostpad) {
-               wfd_sink_error("failed to create ghostpad of audio sinkbin");
-               goto CREATE_ERROR;
-       }
-
-       if (FALSE == gst_element_add_pad(a_sinkbin[WFD_SINK_A_S_BIN].gst, ghostpad)) {
-               wfd_sink_error("failed to add ghostpad to audio sinkbin");
-               goto CREATE_ERROR;
-       }
-       gst_object_unref(GST_OBJECT(pad));
-
-       g_list_free(element_bucket);
-
-       /* take it */
-       wfd_sink->pipeline->a_sinkbin = a_sinkbin;
-
-       wfd_sink_debug_fleave();
-
-       return MM_ERROR_NONE;
-
-CREATE_ERROR:
-       wfd_sink_error("failed to create audio sinkbin, releasing all");
-
-       if (pad)
-               gst_object_unref(GST_OBJECT(pad));
-       pad = NULL;
-
-       if (ghostpad)
-               gst_object_unref(GST_OBJECT(ghostpad));
-       ghostpad = NULL;
-
-       if (element_bucket)
-               g_list_free(element_bucket);
-       element_bucket = NULL;
-
-       /* release element which are not added to bin */
-       for (i = 1; i < WFD_SINK_A_S_NUM; i++) {        /* NOTE : skip bin */
-               if (a_sinkbin != NULL && a_sinkbin[i].gst) {
-                       GstObject *parent = NULL;
-                       parent = gst_element_get_parent(a_sinkbin[i].gst);
-
-                       if (!parent) {
-                               gst_object_unref(GST_OBJECT(a_sinkbin[i].gst));
-                               a_sinkbin[i].gst = NULL;
-                       } else {
-                               gst_object_unref(GST_OBJECT(parent));
-                       }
-               }
-       }
-
-       /* release audio sinkbin with it's childs */
-       if (a_sinkbin != NULL && a_sinkbin[WFD_SINK_A_S_BIN].gst)
-               gst_object_unref(GST_OBJECT(a_sinkbin[WFD_SINK_A_S_BIN].gst));
-
-       MMWFDSINK_FREEIF(a_sinkbin);
-
-       return MM_ERROR_WFD_INTERNAL;
-}
-
-int __mm_wfd_sink_link_video_decodebin(mm_wfd_sink_t *wfd_sink)
-{
-       MMWFDSinkGstElement *v_decodebin = NULL;
-       MMWFDSinkGstElement *first_element = NULL;
-       MMWFDSinkGstElement *last_element = NULL;
-       GList *element_bucket = NULL;
-       GstPad *sinkpad = NULL;
-       GstPad *srcpad = NULL;
-       GstPad *ghostpad = NULL;
-       GList *first_list = NULL;
-       GList *last_list = NULL;
-
-       wfd_sink_debug_fenter();
-
-       wfd_sink_return_val_if_fail(wfd_sink &&
-                                               wfd_sink->pipeline &&
-                                               wfd_sink->pipeline->v_decodebin &&
-                                               wfd_sink->pipeline->v_decodebin[WFD_SINK_V_D_BIN].gst,
-                                               MM_ERROR_WFD_NOT_INITIALIZED);
-
-       if (wfd_sink->video_decodebin_is_linked) {
-               wfd_sink_debug("video decodebin is already linked... nothing to do");
-               return MM_ERROR_NONE;
-       }
-
-       /* take video decodebin */
-       v_decodebin = wfd_sink->pipeline->v_decodebin;
-
-       /* check video queue */
-       if (v_decodebin[WFD_SINK_V_D_QUEUE].gst)
-               element_bucket = g_list_append(element_bucket, &v_decodebin[WFD_SINK_V_D_QUEUE]);
-
-       /* check video hdcp */
-       if (v_decodebin[WFD_SINK_V_D_HDCP].gst)
-               element_bucket = g_list_append(element_bucket, &v_decodebin[WFD_SINK_V_D_HDCP]);
-
-       /* check video codec */
-       switch (wfd_sink->stream_info.video_stream_info.codec) {
-               case MM_WFD_SINK_VIDEO_CODEC_H264:
-                       if (v_decodebin[WFD_SINK_V_D_PARSE].gst)
-                               element_bucket = g_list_append(element_bucket, &v_decodebin[WFD_SINK_V_D_PARSE]);
-                       if (v_decodebin[WFD_SINK_V_D_CAPSSETTER].gst) {
-                               GstCaps *caps = NULL;
-
-                               element_bucket = g_list_append(element_bucket, &v_decodebin[WFD_SINK_V_D_CAPSSETTER]);
-                               caps = gst_caps_new_simple("video/x-h264",
-                                                                       "width", G_TYPE_INT, wfd_sink->stream_info.video_stream_info.width,
-                                                                       "height", G_TYPE_INT, wfd_sink->stream_info.video_stream_info.height,
-                                                                       "framerate", GST_TYPE_FRACTION, wfd_sink->stream_info.video_stream_info.frame_rate, 1, NULL);
-                               g_object_set(G_OBJECT(v_decodebin[WFD_SINK_V_D_CAPSSETTER].gst), "caps", caps, NULL);
-                               gst_object_unref(GST_OBJECT(caps));
-                       }
-                       if (v_decodebin[WFD_SINK_V_D_DEC].gst)
-                               element_bucket = g_list_append(element_bucket, &v_decodebin[WFD_SINK_V_D_DEC]);
-                       break;
-
-               default:
-                       wfd_sink_error("video codec is not decied yet. cannot link video decpdebin...");
-                       return MM_ERROR_WFD_INTERNAL;
-                       break;
-       }
-
-       if (element_bucket == NULL) {
-               wfd_sink_error("there are no elements to be linked in the video decodebin, destroy it");
-               if (MM_ERROR_NONE != __mm_wfd_sink_destroy_video_decodebin(wfd_sink)) {
-                       wfd_sink_error("failed to destroy video decodebin");
-                       goto fail_to_link;
-               }
-               goto done;
-       }
-
-       /* adding elements to video decodebin */
-       if (!__mm_wfd_sink_gst_element_add_bucket_to_bin(GST_BIN_CAST(v_decodebin[WFD_SINK_V_D_BIN].gst), element_bucket, FALSE)) {
-               wfd_sink_error("failed to add elements to video decodebin");
-               goto fail_to_link;
-       }
-
-       /* linking elements in the bucket by added order. */
-       if (__mm_wfd_sink_gst_element_link_bucket(element_bucket) == -1) {
-               wfd_sink_error("failed to link elements of the video decodebin");
-               goto fail_to_link;
-       }
-
-       /* get first element's sinkpad for creating ghostpad */
-       first_list = g_list_first(element_bucket);
-       if (first_list == NULL) {
-               wfd_sink_error("failed to get first list of the element_bucket");
-               goto fail_to_link;
-       }
-
-       first_element = (MMWFDSinkGstElement *)first_list->data;
-       if (!first_element) {
-               wfd_sink_error("failed to get first element of the video decodebin");
-               goto fail_to_link;
-       }
-
-       sinkpad = gst_element_get_static_pad(GST_ELEMENT(first_element->gst), "sink");
-       if (!sinkpad) {
-               wfd_sink_error("failed to get sink pad from element(%s)",
-                       GST_STR_NULL(GST_ELEMENT_NAME(first_element->gst)));
-               goto fail_to_link;
-       }
-
-       ghostpad = gst_ghost_pad_new("sink", sinkpad);
-       if (!ghostpad) {
-               wfd_sink_error("failed to create ghostpad of video decodebin");
-               goto fail_to_link;
-       }
-
-       if (FALSE == gst_element_add_pad(v_decodebin[WFD_SINK_V_D_BIN].gst, ghostpad)) {
-               wfd_sink_error("failed to add ghostpad to video decodebin");
-               goto fail_to_link;
-       }
-       gst_object_unref(GST_OBJECT(sinkpad));
-       sinkpad = NULL;
-
-
-       /* get last element's src for creating ghostpad */
-       last_list = g_list_last(element_bucket);
-       if (last_list == NULL) {
-               wfd_sink_error("failed to get last list of the element_bucket");
-               goto fail_to_link;
-       }
-
-       last_element = (MMWFDSinkGstElement *)last_list->data;
-       if (!last_element) {
-               wfd_sink_error("failed to get last element of the video decodebin");
-               goto fail_to_link;
-       }
-
-       srcpad = gst_element_get_static_pad(GST_ELEMENT(last_element->gst), "src");
-       if (!srcpad) {
-               wfd_sink_error("failed to get src pad from element(%s)",
-                       GST_STR_NULL(GST_ELEMENT_NAME(last_element->gst)));
-               goto fail_to_link;
-       }
-
-       ghostpad = gst_ghost_pad_new("src", srcpad);
-       if (!ghostpad) {
-               wfd_sink_error("failed to create ghostpad of video decodebin");
-               goto fail_to_link;
-       }
-
-       if (FALSE == gst_element_add_pad(v_decodebin[WFD_SINK_V_D_BIN].gst, ghostpad)) {
-               wfd_sink_error("failed to add ghostpad to video decodebin");
-               goto fail_to_link;
-       }
-       gst_object_unref(GST_OBJECT(srcpad));
-       srcpad = NULL;
-
-       g_list_free(element_bucket);
-
-done:
-       wfd_sink->video_decodebin_is_linked = TRUE;
-
-       wfd_sink_debug_fleave();
-
-       return MM_ERROR_NONE;
-
-       /* ERRORS*/
-fail_to_link:
-       if (srcpad != NULL)
-               gst_object_unref(GST_OBJECT(srcpad));
-       srcpad = NULL;
-
-       if (sinkpad != NULL)
-               gst_object_unref(GST_OBJECT(sinkpad));
-       sinkpad = NULL;
-
-       g_list_free(element_bucket);
-
-       return MM_ERROR_WFD_INTERNAL;
-}
-
-static int __mm_wfd_sink_prepare_videodec(mm_wfd_sink_t *wfd_sink, GstElement *video_dec)
-{
-       wfd_sink_debug_fenter();
-
-       /* check video decoder is created */
-       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);
-
-       wfd_sink_debug_fleave();
-
-       return MM_ERROR_NONE;
-}
-
-static int __mm_wfd_sink_prepare_videosink(mm_wfd_sink_t *wfd_sink, GstElement *video_sink)
-{
-       gboolean visible = TRUE;
-       gint surface_type = MM_DISPLAY_SURFACE_OVERLAY;
-
-       wfd_sink_debug_fenter();
-
-       /* check videosink is created */
-       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);
-       wfd_sink_debug("check display surface type attribute: %d", surface_type);
-       mm_attrs_get_int_by_name(wfd_sink->attrs, "display_visible", &visible);
-       wfd_sink_debug("check display visible attribute: %d", visible);
-
-       /* configuring display */
-       switch (surface_type) {
-               case MM_DISPLAY_SURFACE_EVAS: {
-                               void *object = NULL;
-                               gint scaling = 0;
-
-                               /* common case if using evas surface */
-                               mm_attrs_get_data_by_name(wfd_sink->attrs, "display_overlay", &object);
-                               mm_attrs_get_int_by_name(wfd_sink->attrs, "display_evas_do_scaling", &scaling);
-                               if (object) {
-                                       wfd_sink_debug("set video param : evas-object %x", object);
-                                       g_object_set(G_OBJECT(video_sink), "evas-object", object, NULL);
-                               } else {
-                                       wfd_sink_error("no evas object");
-                                       return MM_ERROR_WFD_INTERNAL;
-                               }
-                       }
-                       break;
-
-               case MM_DISPLAY_SURFACE_OVERLAY: {
-                               int wl_window_x = 0;
-                               int wl_window_y = 0;
-                               int wl_window_width = 0;
-                               int wl_window_height = 0;
-                               unsigned int wl_surface_id = 0;
-                               struct wl_surface *wl_surface = NULL;
-                               struct wl_display *wl_display = NULL;
-                               Ecore_Wl_Window *wl_window = NULL;
-                               wl_client *wlclient = NULL;
-                               Evas_Object *obj = NULL;
-                               void *object = NULL;
-                               const char *object_type = NULL;
-                               int ret = 0;
-
-                               mm_attrs_get_data_by_name(wfd_sink->attrs, "display_overlay", &object);
-
-                               if (object != NULL) {
-                                       obj = (Evas_Object *)object;
-                                       object_type = evas_object_type_get(obj);
-                                       wfd_sink_debug("window object type : %s", object_type);
-
-                                       /* wayland overlay surface */
-                                       LOGI("Wayland overlay surface type");
-                                       evas_object_geometry_get(obj, &wl_window_x, &wl_window_y, &wl_window_width, &wl_window_height);
-
-                                       wfd_sink_debug ("x[%d] y[%d] width[%d] height[%d]", wl_window_x, wl_window_y,
-                                               wl_window_width, wl_window_height);
-
-                                       wl_window = elm_win_wl_window_get(obj);
-                                       wl_surface = (struct wl_surface *) ecore_wl_window_surface_get(wl_window);
-
-                                       /* get wl_display */
-                                       wl_display = (struct wl_display *) ecore_wl_display_get();
-
-                                       ret = mm_wfd_sink_wlclient_create(&wlclient);
-                                       if ( ret != MM_ERROR_NONE) {
-                                               wfd_sink_error("Wayland client create failure");
-                                               return ret;
-                               }
-
-                                       if (wl_surface && wl_display){
-                                               wfd_sink_debug ("surface = %p, wl_display = %p", wl_surface, wl_display);
-                                               wl_surface_id = mm_wfd_sink_wlclient_get_wl_window_wl_surface_id (wlclient, wl_surface, wl_display);
-                                               wfd_sink_debug ("wl_surface_id = %d", wl_surface_id);
-                                       }
-                                       if (wlclient) {
-                                               g_free(wlclient);
-                                               wlclient = NULL;
-                                       }
-
-                                       wfd_sink_debug("set video param : surface_id %d", wl_surface_id);
-                                       gst_video_overlay_set_window_handle(GST_VIDEO_OVERLAY(video_sink),
-                                               wl_surface_id);
-                                       /* After setting window handle, set render rectangle */
-                                       gst_video_overlay_set_render_rectangle(GST_VIDEO_OVERLAY(video_sink),
-                                               wl_window_x, wl_window_y, wl_window_width, wl_window_height);
-                               } else {
-                                       wfd_sink_debug ("display object is NULL!");
-                                       return MM_ERROR_WFD_INTERNAL;
-                               }
-                       }
-                       break;
-
-               case MM_DISPLAY_SURFACE_NULL: {
-                               /* do nothing */
-                               wfd_sink_error("Not Supported Surface.");
-                               return MM_ERROR_WFD_INTERNAL;
-                       }
-                       break;
-               default: {
-                               wfd_sink_error("Not Supported Surface.(default case)");
-                               return MM_ERROR_WFD_INTERNAL;
-                       }
-                       break;
-       }
-
-       g_object_set(G_OBJECT(video_sink), "qos", 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);
-       g_object_set(G_OBJECT(video_sink), "ts-offset", (gint64)(wfd_sink->ini.sink_ts_offset), NULL);
-
-       wfd_sink_debug_fleave();
-
-       return MM_ERROR_NONE;
-}
-
-static int __mm_wfd_sink_destroy_video_decodebin(mm_wfd_sink_t *wfd_sink)
-{
-       GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
-       MMWFDSinkGstElement *v_decodebin = 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->v_decodebin &&
-           wfd_sink->pipeline->v_decodebin[WFD_SINK_V_D_BIN].gst) {
-               v_decodebin = wfd_sink->pipeline->v_decodebin;
-       } else {
-               wfd_sink_debug("video decodebin is not created, nothing to destroy");
-               return MM_ERROR_NONE;
-       }
-
-
-       parent = gst_element_get_parent(v_decodebin[WFD_SINK_V_D_BIN].gst);
-       if (!parent) {
-               wfd_sink_debug("video decodebin has no parent.. need to relase by itself");
-
-               if (GST_STATE(v_decodebin[WFD_SINK_V_D_BIN].gst) >= GST_STATE_READY) {
-                       wfd_sink_debug("try to change state of video decodebin to NULL");
-                       ret = gst_element_set_state(v_decodebin[WFD_SINK_V_D_BIN].gst, GST_STATE_NULL);
-                       if (ret != GST_STATE_CHANGE_SUCCESS) {
-                               wfd_sink_error("failed to change state of video decodebin to NULL");
-                               return MM_ERROR_WFD_INTERNAL;
-                       }
-               }
-               /* release element which are not added to bin */
-               for (i = 1; i < WFD_SINK_V_D_NUM; i++) {        /* NOTE : skip bin */
-                       if (v_decodebin[i].gst) {
-                               parent = gst_element_get_parent(v_decodebin[i].gst);
-                               if (!parent) {
-                                       wfd_sink_debug("unref %s(current ref %d)",
-                                                               GST_STR_NULL(GST_ELEMENT_NAME(v_decodebin[i].gst)),
-                                                               ((GObject *) v_decodebin[i].gst)->ref_count);
-                                       gst_object_unref(GST_OBJECT(v_decodebin[i].gst));
-                                       v_decodebin[i].gst = NULL;
-                               } else {
-                                       wfd_sink_debug("unref %s(current ref %d)",
-                                                               GST_STR_NULL(GST_ELEMENT_NAME(v_decodebin[i].gst)),
-                                                               ((GObject *) v_decodebin[i].gst)->ref_count);
-                                       gst_object_unref(GST_OBJECT(parent));
-                               }
-                       }
-               }
-               /* release video decodebin with it's childs */
-               if (v_decodebin[WFD_SINK_V_D_BIN].gst) {
-                       gst_object_unref(GST_OBJECT(v_decodebin[WFD_SINK_V_D_BIN].gst));
-                       wfd_sink_debug("unref %s(current ref %d)",
-                                               GST_STR_NULL(GST_ELEMENT_NAME(v_decodebin[WFD_SINK_V_D_BIN].gst)),
-                                               ((GObject *)v_decodebin[WFD_SINK_V_D_BIN].gst)->ref_count);
-               }
-       } else {
-               wfd_sink_debug("video decodebin has parent(%s), unref it",
-                                       GST_STR_NULL(GST_OBJECT_NAME(GST_OBJECT(parent))));
-
-               gst_object_unref(GST_OBJECT(parent));
-       }
-
-       wfd_sink->video_decodebin_is_linked = FALSE;
-
-       MMWFDSINK_FREEIF(wfd_sink->pipeline->v_decodebin);
-
-       wfd_sink_debug_fleave();
-
-       return MM_ERROR_NONE;
-}
-
-static int __mm_wfd_sink_create_video_decodebin(mm_wfd_sink_t *wfd_sink)
-{
-       MMWFDSinkGstElement *v_decodebin = NULL;
-       guint video_codec = WFD_VIDEO_UNKNOWN;
-       GList *element_bucket = NULL;
-       gboolean link = TRUE;
-       gint i = 0;
-
-       wfd_sink_debug_fenter();
-
-       wfd_sink_return_val_if_fail(wfd_sink &&
-                                               wfd_sink->pipeline,
-                                               MM_ERROR_WFD_NOT_INITIALIZED);
-
-       if (wfd_sink->pipeline->v_decodebin) {
-               wfd_sink_debug("video decodebin is already created... nothing to do");
-               return MM_ERROR_NONE;
-       }
-
-       /* check audio decodebin could be linked now */
-       switch (wfd_sink->stream_info.video_stream_info.codec) {
-               case MM_WFD_SINK_VIDEO_CODEC_H264:
-                       video_codec = WFD_VIDEO_H264;
-                       link = TRUE;
-                       break;
-               case MM_WFD_SINK_VIDEO_CODEC_NONE:
-               default:
-                       wfd_sink_debug("video decodebin could NOT be linked now, just create");
-                       video_codec = wfd_sink->ini.video_codec;
-                       link = FALSE;
-                       break;
-       }
-
-       /* alloc handles */
-       v_decodebin = (MMWFDSinkGstElement *)g_malloc0(sizeof(MMWFDSinkGstElement) * WFD_SINK_V_D_NUM);
-       if (!v_decodebin) {
-               wfd_sink_error("failed to allocate memory for video decodebin");
-               return MM_ERROR_WFD_NO_FREE_SPACE;
-       }
-
-       memset(v_decodebin, 0, sizeof(MMWFDSinkGstElement) * WFD_SINK_V_D_NUM);
-
-       /* create video decodebin */
-       v_decodebin[WFD_SINK_V_D_BIN].id = WFD_SINK_V_D_BIN;
-       v_decodebin[WFD_SINK_V_D_BIN].gst = gst_bin_new("video_decodebin");
-       if (!v_decodebin[WFD_SINK_V_D_BIN].gst) {
-               wfd_sink_error("failed to create video decodebin");
-               goto CREATE_ERROR;
-       }
-
-       /* create queue */
-       MMWFDSINK_CREATE_ELEMENT(v_decodebin, WFD_SINK_V_D_QUEUE, "queue", "video_queue", FALSE);
-       MMWFDSINK_PAD_PROBE(wfd_sink, NULL, v_decodebin[WFD_SINK_V_D_QUEUE].gst,  "sink");
-       if (v_decodebin[WFD_SINK_V_D_QUEUE].gst)
-               __mm_wfd_sink_prepare_queue(wfd_sink, v_decodebin[WFD_SINK_V_D_QUEUE].gst);
-
-       /* create hdcp */
-       MMWFDSINK_CREATE_ELEMENT(v_decodebin, WFD_SINK_V_D_HDCP, wfd_sink->ini.name_of_video_hdcp, "video_hdcp", FALSE);
-       MMWFDSINK_PAD_PROBE(wfd_sink, NULL, v_decodebin[WFD_SINK_V_D_HDCP].gst,  "sink");
-       MMWFDSINK_PAD_PROBE(wfd_sink, NULL, v_decodebin[WFD_SINK_V_D_HDCP].gst,  "src");
-
-       if (video_codec & WFD_VIDEO_H264) {
-               /* create parser */
-               MMWFDSINK_CREATE_ELEMENT(v_decodebin, WFD_SINK_V_D_PARSE, wfd_sink->ini.name_of_video_parser, "video_parser", FALSE);
-               MMWFDSINK_PAD_PROBE(wfd_sink, NULL, v_decodebin[WFD_SINK_V_D_PARSE].gst,  "sink");
-               MMWFDSINK_PAD_PROBE(wfd_sink, NULL, v_decodebin[WFD_SINK_V_D_PARSE].gst,  "src");
-
-               /* create capssetter */
-               MMWFDSINK_CREATE_ELEMENT(v_decodebin, WFD_SINK_V_D_CAPSSETTER, wfd_sink->ini.name_of_video_capssetter, "video_capssetter", FALSE);
-               MMWFDSINK_PAD_PROBE(wfd_sink, NULL, v_decodebin[WFD_SINK_V_D_CAPSSETTER].gst,  "sink");
-               MMWFDSINK_PAD_PROBE(wfd_sink, NULL, v_decodebin[WFD_SINK_V_D_CAPSSETTER].gst,  "src");
-
-               /* create dec */
-               MMWFDSINK_CREATE_ELEMENT(v_decodebin, WFD_SINK_V_D_DEC, wfd_sink->ini.name_of_video_decoder, "video_dec", FALSE);
-               MMWFDSINK_PAD_PROBE(wfd_sink, NULL, v_decodebin[WFD_SINK_V_D_DEC].gst,  "sink");
-               MMWFDSINK_PAD_PROBE(wfd_sink, NULL, v_decodebin[WFD_SINK_V_D_DEC].gst,  "src");
-               if (v_decodebin[WFD_SINK_V_D_DEC].gst) {
-                       if (MM_ERROR_NONE != __mm_wfd_sink_prepare_videodec(wfd_sink, v_decodebin[WFD_SINK_V_D_DEC].gst)) {
-                               wfd_sink_error("failed to set video decoder property...");
-                               goto CREATE_ERROR;
-                       }
-               }
-       }
-
-       g_list_free(element_bucket);
-
-       /* take it */
-       wfd_sink->pipeline->v_decodebin = v_decodebin;
-
-       /* link video decodebin if video codec is fixed */
-       if (link) {
-               if (MM_ERROR_NONE != __mm_wfd_sink_link_video_decodebin(wfd_sink)) {
-                       wfd_sink_error("failed to link video decodebin, destroy video decodebin");
-                       __mm_wfd_sink_destroy_video_decodebin(wfd_sink);
-                       return MM_ERROR_WFD_INTERNAL;
-               }
-       }
-
-       wfd_sink_debug_fleave();
-
-       return MM_ERROR_NONE;
-
-       /* ERRORS */
-CREATE_ERROR:
-       wfd_sink_error("failed to create video decodebin, releasing all");
-
-       g_list_free(element_bucket);
-
-       /* release element which are not added to bin */
-       for (i = 1; i < WFD_SINK_V_D_NUM; i++) {        /* NOTE : skip bin */
-               if (v_decodebin != NULL && v_decodebin[i].gst) {
-                       GstObject *parent = NULL;
-                       parent = gst_element_get_parent(v_decodebin[i].gst);
-
-                       if (!parent) {
-                               gst_object_unref(GST_OBJECT(v_decodebin[i].gst));
-                               v_decodebin[i].gst = NULL;
-                       } else {
-                               gst_object_unref(GST_OBJECT(parent));
-                       }
-               }
-       }
-
-       /* release video decodebin with it's childs */
-       if (v_decodebin != NULL && v_decodebin[WFD_SINK_V_D_BIN].gst)
-               gst_object_unref(GST_OBJECT(v_decodebin[WFD_SINK_V_D_BIN].gst));
-
-       MMWFDSINK_FREEIF(v_decodebin);
-
-       return MM_ERROR_WFD_INTERNAL;
-}
-
-static int __mm_wfd_sink_destroy_video_sinkbin(mm_wfd_sink_t *wfd_sink)
-{
-       GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
-       MMWFDSinkGstElement *v_sinkbin = 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->v_sinkbin &&
-           wfd_sink->pipeline->v_sinkbin[WFD_SINK_V_S_BIN].gst) {
-               v_sinkbin = wfd_sink->pipeline->v_sinkbin;
-       } else {
-               wfd_sink_debug("video sinkbin is not created, nothing to destroy");
-               return MM_ERROR_NONE;
-       }
-
-
-       parent = gst_element_get_parent(v_sinkbin[WFD_SINK_V_S_BIN].gst);
-       if (!parent) {
-               wfd_sink_debug("video sinkbin has no parent.. need to relase by itself");
-
-               if (GST_STATE(v_sinkbin[WFD_SINK_V_S_BIN].gst) >= GST_STATE_READY) {
-                       wfd_sink_debug("try to change state of video sinkbin to NULL");
-                       ret = gst_element_set_state(v_sinkbin[WFD_SINK_V_S_BIN].gst, GST_STATE_NULL);
-                       if (ret != GST_STATE_CHANGE_SUCCESS) {
-                               wfd_sink_error("failed to change state of video sinkbin to NULL");
-                               return MM_ERROR_WFD_INTERNAL;
-                       }
-               }
-               /* release element which are not added to bin */
-               for (i = 1; i < WFD_SINK_V_S_NUM; i++) {        /* NOTE : skip bin */
-                       if (v_sinkbin[i].gst) {
-                               parent = gst_element_get_parent(v_sinkbin[i].gst);
-                               if (!parent) {
-                                       wfd_sink_debug("unref %s(current ref %d)",
-                                                               GST_STR_NULL(GST_ELEMENT_NAME(v_sinkbin[i].gst)),
-                                                               ((GObject *) v_sinkbin[i].gst)->ref_count);
-                                       gst_object_unref(GST_OBJECT(v_sinkbin[i].gst));
-                                       v_sinkbin[i].gst = NULL;
-                               } else {
-                                       wfd_sink_debug("unref %s(current ref %d)",
-                                                               GST_STR_NULL(GST_ELEMENT_NAME(v_sinkbin[i].gst)),
-                                                               ((GObject *) v_sinkbin[i].gst)->ref_count);
-                                       gst_object_unref(GST_OBJECT(parent));
-                               }
-                       }
-               }
-               /* release video sinkbin with it's childs */
-               if (v_sinkbin[WFD_SINK_V_S_BIN].gst) {
-                       gst_object_unref(GST_OBJECT(v_sinkbin[WFD_SINK_V_S_BIN].gst));
-               }
-       } else {
-               wfd_sink_debug("video sinkbin has parent(%s), unref it ",
-                                       GST_STR_NULL(GST_OBJECT_NAME(GST_OBJECT(parent))));
-
-               gst_object_unref(GST_OBJECT(parent));
-       }
-
-       MMWFDSINK_FREEIF(wfd_sink->pipeline->v_sinkbin);
-
-       wfd_sink_debug_fleave();
-
-       return MM_ERROR_NONE;
-}
-
-static int __mm_wfd_sink_create_video_sinkbin(mm_wfd_sink_t *wfd_sink)
-{
-       MMWFDSinkGstElement *first_element = NULL;
-       MMWFDSinkGstElement *v_sinkbin = NULL;
-       GList *element_bucket = NULL;
-       GstPad *pad = NULL;
-       GstPad *ghostpad = NULL;
-       gint i = 0;
-       gint surface_type = MM_DISPLAY_SURFACE_OVERLAY;
-
-       wfd_sink_debug_fenter();
-
-       wfd_sink_return_val_if_fail(wfd_sink &&
-                                               wfd_sink->pipeline,
-                                               MM_ERROR_WFD_NOT_INITIALIZED);
-
-       /* alloc handles */
-       v_sinkbin = (MMWFDSinkGstElement *)g_malloc0(sizeof(MMWFDSinkGstElement) * WFD_SINK_V_S_NUM);
-       if (!v_sinkbin) {
-               wfd_sink_error("failed to allocate memory for video sinkbin");
-               return MM_ERROR_WFD_NO_FREE_SPACE;
-       }
-
-       memset(v_sinkbin, 0, sizeof(MMWFDSinkGstElement) * WFD_SINK_V_S_NUM);
-
-       /* create video sinkbin */
-       v_sinkbin[WFD_SINK_V_S_BIN].id = WFD_SINK_V_S_BIN;
-       v_sinkbin[WFD_SINK_V_S_BIN].gst = gst_bin_new("video_sinkbin");
-       if (!v_sinkbin[WFD_SINK_V_S_BIN].gst) {
-               wfd_sink_error("failed to create video sinkbin");
-               goto CREATE_ERROR;
-       }
-
-       /* create convert */
-       MMWFDSINK_CREATE_ELEMENT(v_sinkbin, WFD_SINK_V_S_CONVERT, wfd_sink->ini.name_of_video_converter, "video_convert", TRUE);
-       MMWFDSINK_PAD_PROBE(wfd_sink, NULL, v_sinkbin[WFD_SINK_V_S_CONVERT].gst,  "sink");
-       MMWFDSINK_PAD_PROBE(wfd_sink, NULL, v_sinkbin[WFD_SINK_V_S_CONVERT].gst,  "src");
-
-       /* create filter */
-       MMWFDSINK_CREATE_ELEMENT(v_sinkbin, WFD_SINK_V_S_FILTER, wfd_sink->ini.name_of_video_filter, "video_filter", TRUE);
-       MMWFDSINK_PAD_PROBE(wfd_sink, NULL, v_sinkbin[WFD_SINK_V_S_FILTER].gst,  "sink");
-       MMWFDSINK_PAD_PROBE(wfd_sink, NULL, v_sinkbin[WFD_SINK_V_S_FILTER].gst,  "src");
-       if (v_sinkbin[WFD_SINK_V_S_FILTER].gst) {
-               GstCaps *caps = NULL;
-               caps = gst_caps_new_simple("video/x-raw", "format", G_TYPE_STRING, "SN12", NULL);
-               g_object_set(G_OBJECT(v_sinkbin[WFD_SINK_V_S_FILTER].gst), "caps", caps, NULL);
-               gst_object_unref(GST_OBJECT(caps));
-       }
-
-       /* create sink */
-       mm_attrs_get_int_by_name(wfd_sink->attrs, "display_surface_type", &surface_type);
-
-       if (surface_type == MM_DISPLAY_SURFACE_OVERLAY) {
-               MMWFDSINK_CREATE_ELEMENT(v_sinkbin, WFD_SINK_V_S_SINK, wfd_sink->ini.name_of_video_sink, "video_sink", TRUE);
-       } else if (surface_type == MM_DISPLAY_SURFACE_EVAS) {
-               MMWFDSINK_CREATE_ELEMENT(v_sinkbin, WFD_SINK_V_S_SINK, wfd_sink->ini.name_of_video_evas_sink, "video_sink", TRUE);
-       } else {
-               wfd_sink_error("failed to set video sink....");
-               goto CREATE_ERROR;
-       }
-
-       MMWFDSINK_PAD_PROBE(wfd_sink, NULL, v_sinkbin[WFD_SINK_V_S_SINK].gst,  "sink");
-       if (v_sinkbin[WFD_SINK_V_S_SINK].gst) {
-               if (MM_ERROR_NONE != __mm_wfd_sink_prepare_videosink(wfd_sink, v_sinkbin[WFD_SINK_V_S_SINK].gst)) {
-                       wfd_sink_error("failed to set video sink property....");
-                       goto CREATE_ERROR;
-               }
-       }
-
-       /* adding created elements to video sinkbin */
-       if (!__mm_wfd_sink_gst_element_add_bucket_to_bin(GST_BIN_CAST(v_sinkbin[WFD_SINK_V_S_BIN].gst), element_bucket, FALSE)) {
-               wfd_sink_error("failed to add elements to video sinkbin");
-               goto CREATE_ERROR;
-       }
-
-       /* linking elements in the bucket by added order. */
-       if (__mm_wfd_sink_gst_element_link_bucket(element_bucket) == -1) {
-               wfd_sink_error("failed to link elements of the video sinkbin");
-               goto CREATE_ERROR;
-       }
-
-       /* get first element's sinkpad for creating ghostpad */
-       first_element = (MMWFDSinkGstElement *)g_list_nth_data(element_bucket, 0);
-       if (!first_element) {
-               wfd_sink_error("failed to get first element of the video sinkbin");
-               goto CREATE_ERROR;
-       }
-
-       pad = gst_element_get_static_pad(GST_ELEMENT(first_element->gst), "sink");
-       if (!pad) {
-               wfd_sink_error("failed to get pad from first element(%s) of the video sinkbin",
-                       GST_STR_NULL(GST_ELEMENT_NAME(first_element->gst)));
-               goto CREATE_ERROR;
-       }
-
-       ghostpad = gst_ghost_pad_new("sink", pad);
-       if (!ghostpad) {
-               wfd_sink_error("failed to create ghostpad of the video sinkbin");
-               goto CREATE_ERROR;
-       }
-
-       if (FALSE == gst_element_add_pad(v_sinkbin[WFD_SINK_V_S_BIN].gst, ghostpad)) {
-               wfd_sink_error("failed to add ghostpad to video sinkbin");
-               goto CREATE_ERROR;
-       }
-
-       gst_object_unref(GST_OBJECT(pad));
-
-       g_list_free(element_bucket);
-
-
-       /* take it */
-       wfd_sink->pipeline->v_sinkbin = v_sinkbin;
-
-       wfd_sink_debug_fleave();
-
-       return MM_ERROR_NONE;
-
-       /* ERRORS */
-CREATE_ERROR:
-       wfd_sink_error("failed to create video sinkbin, releasing all");
-
-       if (pad)
-               gst_object_unref(GST_OBJECT(pad));
-       pad = NULL;
-
-       if (ghostpad)
-               gst_object_unref(GST_OBJECT(ghostpad));
-       ghostpad = NULL;
-
-       g_list_free(element_bucket);
-
-       /* release element which are not added to bin */
-       for (i = 1; i < WFD_SINK_V_S_NUM; i++) {        /* NOTE : skip bin */
-               if (v_sinkbin != NULL && v_sinkbin[i].gst) {
-                       GstObject *parent = NULL;
-                       parent = gst_element_get_parent(v_sinkbin[i].gst);
-
-                       if (!parent) {
-                               gst_object_unref(GST_OBJECT(v_sinkbin[i].gst));
-                               v_sinkbin[i].gst = NULL;
-                       } else {
-                               gst_object_unref(GST_OBJECT(parent));
-                       }
-               }
-       }
-
-       /* release video sinkbin with it's childs */
-       if (v_sinkbin != NULL && v_sinkbin[WFD_SINK_V_S_BIN].gst)
-               gst_object_unref(GST_OBJECT(v_sinkbin[WFD_SINK_V_S_BIN].gst));
-
-       MMWFDSINK_FREEIF(v_sinkbin);
-
-       return MM_ERROR_WFD_INTERNAL;
-}
-
-static int __mm_wfd_sink_destroy_pipeline(mm_wfd_sink_t *wfd_sink)
-{
-       GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
-
-       wfd_sink_debug_fenter();
-
-       wfd_sink_return_val_if_fail(wfd_sink, MM_ERROR_WFD_NOT_INITIALIZED);
-
-       /* cleanup gst stuffs */
-       if (wfd_sink->pipeline) {
-               MMWFDSinkGstElement *mainbin = wfd_sink->pipeline->mainbin;
-
-               if (mainbin) {
-                       ret = gst_element_set_state(mainbin[WFD_SINK_M_PIPE].gst, GST_STATE_NULL);
-                       if (ret != GST_STATE_CHANGE_SUCCESS) {
-                               wfd_sink_error("failed to change state of mainbin to NULL");
-                               return MM_ERROR_WFD_INTERNAL;
-                       }
-
-                       if (MM_ERROR_NONE != __mm_wfd_sink_destroy_video_decodebin(wfd_sink)) {
-                               wfd_sink_error("failed to destroy video decodebin");
-                               return MM_ERROR_WFD_INTERNAL;
-                       }
-
-                       if (MM_ERROR_NONE != __mm_wfd_sink_destroy_audio_decodebin(wfd_sink)) {
-                               wfd_sink_error("failed to destroy audio decodebin");
-                               return MM_ERROR_WFD_INTERNAL;
-                       }
-
-                       if (MM_ERROR_NONE != __mm_wfd_sink_destroy_video_sinkbin(wfd_sink)) {
-                               wfd_sink_error("failed to destroy video sinkbin");
-                               return MM_ERROR_WFD_INTERNAL;
-                       }
-
-                       if (MM_ERROR_NONE != __mm_wfd_sink_destroy_audio_sinkbin(wfd_sink)) {
-                               wfd_sink_error("failed to destroy audio sinkbin");
-                               return MM_ERROR_WFD_INTERNAL;
-                       }
-
-                       gst_object_unref(GST_OBJECT(mainbin[WFD_SINK_M_PIPE].gst));
-
-                       MMWFDSINK_FREEIF(mainbin);
-               }
-
-               MMWFDSINK_FREEIF(wfd_sink->pipeline);
-       }
-
-       wfd_sink->audio_decodebin_is_linked = FALSE;
-       wfd_sink->video_decodebin_is_linked = FALSE;
-       wfd_sink->need_to_reset_basetime = FALSE;
-
-       wfd_sink_debug_fleave();
-
-       return MM_ERROR_NONE;
-}
-
-static void
-__mm_wfd_sink_dump_pipeline_state(mm_wfd_sink_t *wfd_sink)
-{
-       GstIterator *iter = NULL;
-       gboolean done = FALSE;
-
-       GstElement *item = NULL;
-       GstElementFactory *factory = NULL;
-
-       GstState state = GST_STATE_VOID_PENDING;
-       GstState pending = GST_STATE_VOID_PENDING;
-       GstClockTime time = 200 * GST_MSECOND;
-
-       wfd_sink_debug_fenter();
-
-       wfd_sink_return_if_fail(wfd_sink &&
-                                               wfd_sink->pipeline &&
-                                               wfd_sink->pipeline->mainbin &&
-                                               wfd_sink->pipeline->mainbin[WFD_SINK_M_PIPE].gst);
-
-       iter = gst_bin_iterate_recurse(GST_BIN(wfd_sink->pipeline->mainbin[WFD_SINK_M_PIPE].gst));
-
-       if (iter != NULL) {
-               while (!done) {
-                       switch (gst_iterator_next(iter, (gpointer)&item)) {
-                               case GST_ITERATOR_OK:
-                                       gst_element_get_state(GST_ELEMENT(item), &state, &pending, time);
-
-                                       factory = gst_element_get_factory(item) ;
-                                       if (factory) {
-                                               wfd_sink_error("%s:%s : From:%s To:%s refcount : %d",
-                                                                       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;
-                               case GST_ITERATOR_RESYNC:
-                                       gst_iterator_resync(iter);
-                                       break;
-                               case GST_ITERATOR_ERROR:
-                                       done = TRUE;
-                                       break;
-                               case GST_ITERATOR_DONE:
-                                       done = TRUE;
-                                       break;
-                               default:
-                                       done = TRUE;
-                                       break;
-                       }
-               }
-       }
-
-       item = GST_ELEMENT_CAST(wfd_sink->pipeline->mainbin[WFD_SINK_M_PIPE].gst);
-
-       gst_element_get_state(GST_ELEMENT(item), &state, &pending, time);
-
-       factory = gst_element_get_factory(item) ;
-       if (factory) {
-               wfd_sink_error("%s:%s : From:%s To:%s refcount : %d",
-                                       GST_OBJECT_NAME(factory),
-                                       GST_ELEMENT_NAME(item),
-                                       gst_element_state_get_name(state),
-                                       gst_element_state_get_name(pending),
-                                       GST_OBJECT_REFCOUNT_VALUE(item));
-       }
-
-       if (iter)
-               gst_iterator_free(iter);
-
-       wfd_sink_debug_fleave();
-
-       return;
-}
-
-const gchar * _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_PREPARED:
-                       return "PREPARED";
-               case MM_WFD_SINK_STATE_CONNECTED:
-                       return "CONNECTED";
-               case MM_WFD_SINK_STATE_PLAYING:
-                       return "PLAYING";
-               case MM_WFD_SINK_STATE_PAUSED:
-                       return "PAUSED";
-               case MM_WFD_SINK_STATE_DISCONNECTED:
-                       return "DISCONNECTED";
-               default:
-                       return "INVAID";
-       }
-}
-
-static void __mm_wfd_sink_prepare_video_resolution(gint resolution, guint *CEA_resolution, guint *VESA_resolution, guint *HH_resolution)
-{
-       if (resolution == MM_WFD_SINK_RESOLUTION_UNKNOWN) return;
-
-       *CEA_resolution = 0;
-       *VESA_resolution = 0;
-       *HH_resolution = 0;
-
-       if (resolution & MM_WFD_SINK_RESOLUTION_1920x1080_P30)
-               *CEA_resolution |= WFD_CEA_1920x1080P30;
-
-       if (resolution & MM_WFD_SINK_RESOLUTION_1280x720_P30)
-               *CEA_resolution |= WFD_CEA_1280x720P30;
-
-       if (resolution & MM_WFD_SINK_RESOLUTION_960x540_P30)
-               *HH_resolution |= WFD_HH_960x540P30;
-
-       if (resolution & MM_WFD_SINK_RESOLUTION_864x480_P30)
-               *HH_resolution |= WFD_HH_864x480P30;
-
-       if (resolution & MM_WFD_SINK_RESOLUTION_720x480_P60)
-               *CEA_resolution |= WFD_CEA_720x480P60;
-
-       if (resolution & MM_WFD_SINK_RESOLUTION_640x480_P60)
-               *CEA_resolution |= WFD_CEA_640x480P60;
-
-       if (resolution & MM_WFD_SINK_RESOLUTION_640x360_P30)
-               *HH_resolution |= WFD_HH_640x360P30;
-}
-
-int _mm_wfd_sink_set_resolution(mm_wfd_sink_t *wfd_sink, MMWFDSinkResolution resolution)
-{
-       MMWFDSinkStateType cur_state = MM_WFD_SINK_STATE_NONE;
-
-       wfd_sink_debug_fenter();
-
-       wfd_sink_return_val_if_fail(wfd_sink, MM_ERROR_WFD_NOT_INITIALIZED);
-
-       MMWFDSINK_PRINT_STATE(wfd_sink);
-       cur_state = MMWFDSINK_CURRENT_STATE(wfd_sink);
-       if (cur_state != MM_WFD_SINK_STATE_NULL) {
-               wfd_sink_error("This function must be called when MM_WFD_SINK_STATE_NULL");
-               return MM_ERROR_WFD_INVALID_STATE;
-       }
-
-       wfd_sink->supportive_resolution = resolution;
-
-       wfd_sink_debug_fleave();
-
-       return MM_ERROR_NONE;
-}
diff --git a/sink/mm_wfd_sink_util.c b/sink/mm_wfd_sink_util.c
deleted file mode 100755 (executable)
index 405a818..0000000
+++ /dev/null
@@ -1,224 +0,0 @@
-/*
- * libmm-wfd
- *
- * Copyright (c) 2011 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
- *
- * Contact: JongHyuk Choi <jhchoi.choi@samsung.com>, ByungWook Jang <bw.jang@samsung.com>,
- * Maksym Ukhanov <m.ukhanov@samsung.com>, Hyunjun Ko <zzoon.ko@samsung.com>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-#include "mm_wfd_sink_util.h"
-#include <stdio.h>
-#include <tzplatform_config.h>
-
-#define DUMP_TS_DATA_PATH tzplatform_mkpath(TZ_SYS_VAR, "tmp/")
-
-static GstPadProbeReturn
-_mm_wfd_sink_util_dump(GstPad *pad, GstPadProbeInfo *info, gpointer u_data)
-{
-       gint8 *data = NULL;
-       gint size = 0;
-       FILE *f = NULL;
-       char buf[256] = {0, };
-       char path[256] = {0, };
-       GstElement * parent = NULL;
-
-       parent = gst_pad_get_parent_element(pad);
-       if (parent == NULL) {
-               wfd_sink_error("The parent of pad is NULL.");
-               return GST_PAD_PROBE_OK;
-       }
-
-       snprintf(path, sizeof(path), "%s%s_%s.ts", DUMP_TS_DATA_PATH, gst_element_get_name(parent), gst_pad_get_name(pad));
-       gst_object_unref(parent);
-
-       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);
-
-               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));
-                       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 GST_PAD_PROBE_OK;
-}
-
-static GstPadProbeReturn
-_mm_wfd_sink_util_pad_probe_cb(GstPad *pad, GstPadProbeInfo *info, gpointer u_data)
-{
-       GstElement *parent = NULL;
-
-       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);
-
-       parent = (GstElement *)gst_object_get_parent(GST_OBJECT(pad));
-       if (!parent) {
-               wfd_sink_error("failed to get parent of pad");
-               return GST_PAD_PROBE_DROP;
-       }
-
-       if (info->type & GST_PAD_PROBE_TYPE_BUFFER) {
-               GstBuffer *buffer = gst_pad_probe_info_get_buffer(info);
-               /* show name and timestamp */
-               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 */
-               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) {
-                       const GstSegment *segment = NULL;
-                       gst_event_parse_segment(event, &segment);
-                       if (segment)
-                               wfd_sink_debug("NEWSEGMENT : %" GST_TIME_FORMAT
-                                                       " -- %"  GST_TIME_FORMAT ", time %" GST_TIME_FORMAT " \n",
-                                                       GST_TIME_ARGS(segment->start), GST_TIME_ARGS(segment->stop),
-                                                       GST_TIME_ARGS(segment->time));
-               }
-       }
-
-       if (parent)
-               gst_object_unref(parent);
-
-       return GST_PAD_PROBE_OK;
-}
-
-void
-mm_wfd_sink_util_add_pad_probe(GstPad *pad, GstElement *element, const gchar *pad_name)
-{
-       GstPad *probe_pad = 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) {
-               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);
-       }
-}
-
-void
-mm_wfd_sink_util_add_pad_probe_for_data_dump(GstElement *element, const gchar *pad_name)
-{
-       GstPad *probe_pad = NULL;
-
-       if (element && pad_name)
-               probe_pad = gst_element_get_static_pad(element, pad_name);
-
-       if (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;
-}
-
diff --git a/sink/mm_wfd_sink_wayland.c b/sink/mm_wfd_sink_wayland.c
deleted file mode 100755 (executable)
index 787dea8..0000000
+++ /dev/null
@@ -1,148 +0,0 @@
-/*
-* 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.
-*/
-
-#include <glib.h>
-#include <string.h>
-#include <mm_error.h>
-#include <wayland-client.h>
-#include <tizen-extension-client-protocol.h>
-
-#include "mm_wfd_sink_dlog.h"
-#include "mm_wfd_sink_wayland.h"
-
-#define goto_if_fail(expr,label)       \
-{      \
-       if (!(expr)) {  \
-               wfd_sink_error(" failed [%s]\n", #expr);        \
-               goto label;     \
-       }       \
-}
-
-void mm_wfd_sink_handle_resource_id(void *data, struct tizen_resource *tizen_resource, uint32_t id)
-{
-       unsigned int *wl_surface_id = data;
-
-       *wl_surface_id = id;
-
-       wfd_sink_debug("[CLIENT] got wl_surface_id(%d) from server\n", id);
-}
-
-static const struct tizen_resource_listener tz_resource_listener =
-{
-       mm_wfd_sink_handle_resource_id,
-};
-
-static void
-mm_wfd_sink_handle_global(void *data, struct wl_registry *registry,
-              uint32_t name, const char *interface, uint32_t version)
-{
-       return_if_fail (data != NULL);
-       wl_client *wlclient = data;
-
-       if (strcmp(interface, "tizen_surface") == 0)
-       {
-               wfd_sink_debug("binding tizen_surface");
-               wlclient->tz_surface = wl_registry_bind(registry, name, &tizen_surface_interface, version);
-               return_if_fail (wlclient->tz_surface != NULL);
-       }
-}
-
-static void mm_wfd_sink_handle_global_remove(void* data, struct wl_registry* registry, uint32_t name)
-{
-       wfd_sink_debug("wl_registry_handle_global_remove");
-}
-
-static const struct wl_registry_listener registry_listener =
-{
-       mm_wfd_sink_handle_global,
-       mm_wfd_sink_handle_global_remove
-};
-
-int mm_wfd_sink_wlclient_create (wl_client ** wlclient)
-{
-       wl_client *ptr = NULL;
-
-       ptr = g_malloc0 (sizeof (wl_client));
-       if (!ptr) {
-               wfd_sink_error ("Cannot allocate memory for wlclient\n");
-               goto ERROR;
-       } else {
-               *wlclient = ptr;
-               wfd_sink_debug ("Success create wlclient(%p)", *wlclient);
-       }
-       return MM_ERROR_NONE;
-
-ERROR:
-       *wlclient = NULL;
-       return MM_ERROR_WFD_NO_FREE_SPACE;
-}
-
-
-int mm_wfd_sink_wlclient_get_wl_window_wl_surface_id (wl_client * wlclient, struct wl_surface *surface, struct wl_display *display)
-{
-       goto_if_fail (wlclient != NULL, failed);
-       goto_if_fail (surface != NULL, failed);
-       goto_if_fail (display != NULL, failed);
-
-       unsigned int wl_surface_id = 0;
-
-       wlclient->display = display;
-       goto_if_fail (wlclient->display != NULL, failed);
-
-       wlclient->registry = wl_display_get_registry(wlclient->display);
-       goto_if_fail (wlclient->registry != NULL, failed);
-
-       wl_registry_add_listener(wlclient->registry, &registry_listener, wlclient);
-       wl_display_dispatch(wlclient->display);
-       wl_display_roundtrip(wlclient->display);
-
-       /* check global objects */
-       goto_if_fail (wlclient->tz_surface != NULL, failed);
-
-       /* Get wl_surface_id which is unique in a entire systemw. */
-       wlclient->tz_resource = tizen_surface_get_tizen_resource(wlclient->tz_surface, surface);
-       goto_if_fail (wlclient->tz_resource != NULL, failed);
-
-       tizen_resource_add_listener(wlclient->tz_resource, &tz_resource_listener, &wl_surface_id);
-       wl_display_roundtrip(wlclient->display);
-       goto_if_fail (wl_surface_id > 0, failed);
-
-       mm_wfd_sink_wlclient_finalize(wlclient);
-
-       return wl_surface_id;
-
-failed:
-       wfd_sink_error ("Failed to get wl_surface_id");
-
-       return 0;
-}
-
-void mm_wfd_sink_wlclient_finalize (wl_client * wlclient)
-{
-       wfd_sink_debug ("start finalize wlclient");
-       return_if_fail (wlclient != NULL)
-
-       if (wlclient->tz_surface)
-               tizen_surface_destroy(wlclient->tz_surface);
-
-       if (wlclient->tz_resource)
-               tizen_resource_destroy(wlclient->tz_resource);
-
-    /* destroy registry */
-       if (wlclient->registry)
-               wl_registry_destroy(wlclient->registry);
-       return;
-}
diff --git a/src/Makefile.am b/src/Makefile.am
new file mode 100755 (executable)
index 0000000..5cd4d59
--- /dev/null
@@ -0,0 +1,48 @@
+lib_LTLIBRARIES = libmmfwfdsink.la
+
+includelibmmfwfdsinkdir = $(includedir)/mmf
+
+includelibmmfwfdsink_HEADERS = include/mm_wfd_sink.h \
+                               include/mm_wfd_sink_ini.h \
+                               include/mm_wfd_sink_priv.h \
+                               include/mm_wfd_sink_dlog.h \
+                               include/mm_wfd_sink_attrs.h \
+                               include/mm_wfd_sink_util.h
+
+libmmfwfdsink_la_SOURCES = mm_wfd_sink_attrs.c \
+                               mm_wfd_sink_ini.c \
+                               mm_wfd_sink_util.c \
+                               mm_wfd_sink.c \
+                               mm_wfd_sink_manager.c \
+                               mm_wfd_sink_priv.c \
+                               mm_wfd_sink_wayland.c
+
+
+libmmfwfdsink_la_CFLAGS = -I$(srcdir)/include \
+                       $(MMCOMMON_CFLAGS) \
+                       $(GST_CFLAGS) \
+                       $(EVAS_CFLAGS) \
+                       $(ELEMENTARY_CFLAGS) \
+                       $(GST_PLUGINS_BASE_CFLAGS) \
+                       $(GST_VIDEO_CFLAGS) \
+                       $(TZPLATFORM_CONFIG_CFLAGS) \
+                       $(AUDIOSESSIONMGR_CFLAGS)
+
+libmmfwfdsink_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
+
+noinst_HEADERS = include/mm_wfd_sink_manager.h \
+               include/mm_wfd_sink_wayland.h \
+               include/mm_wfd_sink_enum.h
+
+libmmfwfdsink_la_LIBADD = $(GST_LIBS) \
+                       $(GST_PLUGINS_BASE_LIBS) \
+                       $(GST_BASE_LIBS) \
+                       $(ELEMENTARY_LIBS) \
+                       $(EVAS_LIBS) \
+                       $(MMCOMMON_LIBS) \
+                       $(AUDIOSESSIONMGR_LIBS) \
+                       $(TZPLATFORM_CONFIG_LIBS) \
+                       $(GST_VIDEO_LIBS)
+
+libmmfwfdsink_la_CFLAGS += $(MMLOG_CFLAGS) -DMMF_LOG_OWNER=0x02000000 -DMMF_DEBUG_PREFIX=\"MMF-WFD-SINK\"
+libmmfwfdsink_la_LIBADD += $(MMLOG_LIBS)
diff --git a/src/include/mm_wfd_sink.h b/src/include/mm_wfd_sink.h
new file mode 100755 (executable)
index 0000000..620324f
--- /dev/null
@@ -0,0 +1,484 @@
+/*
+ * libmm-wfd
+ *
+ * Copyright (c) 2011 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: JongHyuk Choi <jhchoi.choi@samsung.com>, ByungWook Jang <bw.jang@samsung.com>,
+ * Maksym Ukhanov <m.ukhanov@samsung.com>, Hyunjun Ko <zzoon.ko@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef _MM_WFD_SINK_H_
+#define _MM_WFD_SINK_H_
+
+#include <string.h>
+#include <glib.h>
+#include <mm_message.h>
+#include <mm_error.h>
+#include <mm_types.h>
+
+/**
+ *  * Enumerations of wifi-display sink state.
+ *   */
+typedef enum {
+       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;
+
+/* audio codec : AAC, AC3, LPCM  */
+typedef enum {
+       MM_WFD_SINK_AUDIO_CODEC_NONE,
+       MM_WFD_SINK_AUDIO_CODEC_AAC = 0x0F,
+       MM_WFD_SINK_AUDIO_CODEC_AC3 = 0x81,
+       MM_WFD_SINK_AUDIO_CODEC_LPCM = 0x83
+} MMWFDSinkAudioCodec;
+
+/* video codec : H264  */
+typedef enum {
+       MM_WFD_SINK_VIDEO_CODEC_NONE,
+       MM_WFD_SINK_VIDEO_CODEC_H264 = 0x1b
+} MMWFDSinkVideoCodec;
+
+typedef void(*MMWFDMessageCallback)(int error_type, MMWFDSinkStateType state_type, void *user_data);
+
+/**
+ * This function creates a wi-fi display sink object. \n
+ * The attributes of wi-fi display sink are created to get/set some values with application. \n
+ * And, mutex, gstreamer and other resources are initialized at this time. \n
+ * If wi-fi display sink is created, he state will become MM_WFD_SINK_STATE_NULL.. \n
+ *
+ * @param      wfd_sink                [out]   Handle of wi-fi display sink
+ *
+ * @return     This function returns zero on success, or negative value with error code. \n
+ *                     Please refer 'mm_error.h' to know it in detail.
+ * @pre                None
+ * @post               MM_WFD_SINK_STATE_NULL
+ * @see                mm_wfd_sink_destroy
+ * @remark     You can create multiple handles on a context at the same time. \n
+ *                     However, wi-fi display sink cannot guarantee proper operation because of limitation of resources, \n
+ *                     such as audio device or display device.
+ *
+ * @par Example
+ * @code
+if (mm_wfd_sink_create(&g_wfd_sink) != MM_ERROR_NONE)
+{
+       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);
+ * @endcode
+ */
+int mm_wfd_sink_create(MMHandleType *wfd_sink);
+
+/**
+ * This function trys to make gstreamer pipeline. \n
+ * If wi-fi display sink is realized, the state will become MM_WFD_SINK_STATE_READY.. \n
+ *
+ * @param      wfd_sink                [out]   Handle of wi-fi display sink
+ *
+ * @return     This function returns zero on success, or negative value with error code. \n
+ *                     Please refer 'mm_error.h' to know it in detail.
+ * @pre                MM_WFD_SINK_STATE_NULL
+ * @post               MM_WFD_SINK_STATE_PREPARED
+ * @see                mm_wfd_sink_unprepare
+ * @remark     None
+ * @par Example
+ * @code
+if (mm_wfd_sink_prepare(&g_wfd_sink) != MM_ERROR_NONE)
+{
+       wfd_sink_error("failed to realize wi-fi display sink\n");
+}
+ * @endcode
+ */
+int mm_wfd_sink_prepare(MMHandleType wfd_sink);
+
+/**
+ * This function connect wi-fi display source using uri. \n
+ * audio type(AC3 AAC, LPCM) is decided at this time. \n
+ *
+ * @param      wfd_sink                [in]    Handle of wi-fi display sink
+ * @param      uri                     [in]    URI of wi-fi displaysource to be connected
+ *
+ * @return     This function returns zero on success, or negative value with error code.
+ *
+ * @pre                wi-fi display sink state should be MM_WFD_SINK_STATE_PREPARED
+ * @post               wi-fi display sink state will be MM_WFD_SINK_STATE_CONNECTED with no preroll.
+ * @remark     None
+ * @par Example
+ * @code
+if (mm_wfd_sink_connect(g_wfd_sink, g_uri) != MM_ERROR_NONE)
+{
+       wfd_sink_error("failed to connect to wi-fi display source\n");
+}
+ * @endcode
+ */
+int mm_wfd_sink_connect(MMHandleType wfd_sink, const char *uri);
+
+/**
+ * This function is to start playing. \n
+ * Data from wi-fi display source will be received. \n
+ *
+ * @param      wfd_sink                [in]    Handle of wi-fi display sink
+ *
+ * @return     This function returns zero on success, or negative value with error code.
+ * @remark
+ *
+ * @pre                wi-fi display sink state may be MM_WFD_SINK_STATE_CONNECTED.
+ * @post               wi-fi display sink state will be MM_WFD_SINK_STATE_PLAYING.
+ * @see                mm_wfd_sink_disconnect
+ * @remark     None
+ * @par Example
+ * @code
+if (mm_wfd_sink_start(g_wfd_sink) != MM_ERROR_NONE)
+{
+       wfd_sink_error("failed to start wi-fi display sink\n");
+}
+ * @endcode
+ */
+int mm_wfd_sink_start(MMHandleType wfd_sink);
+
+/**
+ * This function is to pause playing. \n
+ * The wi-fi display sink pause the current stream being received form wi-fi display source. \n
+ *
+ * @param      wfd_sink                [in]    Handle of wi-fi display sink
+ *
+ * @return     This function returns zero on success, or negative value with error code.
+ * @remark
+ *
+ * @pre                wi-fi display sink state should be MM_WFD_SINK_STATE_PLAYING.
+ * @post               wi-fi display sink state will be MM_WFD_SINK_STATE_PAUSED.
+ * @see                mm_wfd_sink_pause
+ * @remark     None
+ * @par Example
+ * @code
+if (mm_wfd_sink_pause(g_wfd_sink) != MM_ERROR_NONE)
+{
+       wfd_sink_error("failed to pause wi-fi display sink\n");
+}
+ * @endcode
+ */
+int mm_wfd_sink_pause(MMHandleType wfd_sink);
+
+/**
+ * This function is to resume playing. \n
+ * Data from wi-fi display source will be received. \n
+ *
+ * @param      wfd_sink                [in]    Handle of wi-fi display sink
+ *
+ * @return     This function returns zero  on success, or negative value with error code.
+ * @remark
+ *
+ * @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_disconnect
+ * @remark     None
+ * @par Example
+ * @code
+if (mm_wfd_sink_start(g_wfd_sink) != MM_ERROR_NONE)
+{
+       wfd_sink_error("failed to resume wi-fi display sink\n");
+}
+ * @endcode
+ */
+int mm_wfd_sink_resume(MMHandleType wfd_sink);
+
+/**
+ * This function is to stop playing wi-fi display. \n
+ *
+ * @param      wfd_sink                [in]    Handle of wi-fi display sink
+ *
+ * @return     This function returns zero on success, or negative value with error code.
+ *
+ * @pre                wi-fi display sink state may be MM_WFD_SINK_STATE_PLAYING.
+ * @post               wi-fi display sink state will be MM_WFD_SINK_STATE_DISCONNECTED.
+ * @see                mm_wfd_sink_start
+ * @remark     None
+ * @par Example
+ * @code
+if (mm_wfd_sink_disconnect(g_wfd_sink) != MM_ERROR_NONE)
+{
+       wfd_sink_error("failed to stop wi-fi display sink\n");
+}
+ * @endcode
+ */
+int mm_wfd_sink_disconnect(MMHandleType wfd_sink);
+
+/**
+ * This function trys to destroy gstreamer pipeline. \n
+ *
+ * @param      wfd_sink                [out]   Handle of wi-fi display sink
+ *
+ * @return     This function returns zero on success, or negative value with error code. \n
+ *                     Please refer 'mm_error.h' to know it in detail.
+ * @pre                wi-fi display sink state may be MM_WFD_SINK_STATE_PREPARED or MM_WFD_SINK_STATE_DISCONNECTED.
+ *                     But, it can be called in any state.
+ * @post               MM_WFD_SINK_STATE_NULL
+ * @see                mm_wfd_sink_prepare
+ * @remark     None
+ * @par Example
+ * @code
+if (mm_wfd_sink_unprepare(&g_wfd_sink) != MM_ERROR_NONE)
+{
+       wfd_sink_error("failed to unprepare wi-fi display sink\n");
+}
+ * @endcode
+ */
+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
+ * And, wi-fi display sink handle will also be destroyed. \n
+ *
+ * @param      wfd_sink                [in]    Handle of wi-fi display sink
+ *
+ * @return     This function returns zero on success, or negative value with error code.
+ * @pre                wi-fi display state may be MM_WFD_SINK_STATE_NULL. \n
+ *                     But, it can be called in any state.
+ * @post               Because handle is released, there is no any state.
+ * @see                mm_wfd_sink_create
+ * @remark     This method can be called with a valid wi-fi display sink handle from any state to \n
+ *                     completely shutdown the wi-fi display sink operation.
+ *
+ * @par Example
+ * @code
+if (mm_wfd_sink_destroy(g_wfd_sink) != MM_ERROR_NONE)
+{
+       wfd_sink_error("failed to destroy wi-fi display sink\n");
+}
+ * @endcode
+ */
+int mm_wfd_sink_destroy(MMHandleType wfd_sink);
+
+/**
+ * This function sets callback function for receiving messages from wi-fi display sink. \n
+ * So, player can notify warning, error and normal cases to application. \n
+ *
+ * @param      wfd_sink                [in]    Handle of wi-fi display sink
+ * @param      callback        [in]    Message callback function.
+ * @param      user_param      [in]    User parameter which is passed to callback function.
+ *
+ * @return     This function returns zero on success, or negative value with error code.
+ * @see                MMWFDMessageCallback
+ * @remark     None
+ * @par Example
+ * @code
+
+int msg_callback(int error_type, MMWFDSinkStateType state_type, void *user_data)
+{
+       switch (state_type)
+       {
+               case MM_WFD_SINK_STATE_NULL:
+                       //do something
+                       break;
+
+               case MM_WFD_SINK_STATE_PREPARED:
+                       //do something
+                       break;
+
+               case MM_WFD_SINK_STATE_CONNECTED:
+                       //do something
+                       break;
+
+               case MM_WFD_SINK_STATE_PLAYING:
+                       //do something
+                       break;
+
+               case MM_WFD_SINK_STATE_PAUSED:
+                       //do something
+                       break;
+
+               case MM_WFD_SINK_DISCONNECTED:
+                       //do something
+                       break;
+
+               default:
+                       break;
+       }
+       return TRUE;
+}
+
+mm_wfd_sink_set_message_callback(g_wfd_sink, msg_callback, (void*)g_wfd_sink);
+ * @endcode
+ */
+int mm_wfd_sink_set_message_callback(MMHandleType wfd_sink, MMWFDMessageCallback callback, void *user_param);
+
+int mm_wfd_sink_set_attribute(MMHandleType wfd_sink,  char **err_attr_name, const char *first_attribute_name, ...);
+
+/**
+ * This function get resources \n
+ *
+ * @param      wfd_sink                [in]    Handle of wi-fi display sink
+ *
+ * @return     This function returns zero on success, or negative value with error code.
+ * @pre                wi-fi display state should be MM_WFD_SINK_STATE_READY or MM_WFD_SINK_STATE_PREPARED. \n
+ * @post               N/A
+ * @remark     resources are released when mm_wfd_sink_destory is called
+ *
+ * @par Example
+ * @code
+if (mm_wfd_sink_get_resource(g_wfd_sink) != MM_ERROR_NONE)
+{
+       wfd_sink_error("failed to get resources for wi-fi display sink\n");
+}
+ * @endcode
+ */
+int mm_wfd_sink_get_resource(MMHandleType wfd_sink);
+
+/**
+ * This function sets the display surface type for wi-fi display sink\n
+ *
+ * @param      wfd_sink                [in]    Handle of wi-fi display sink
+ * @param      display_surface_type            [in]    Display surface type
+ *
+ * @return     This function returns zero on success, or negative value with error code.
+ * @pre                wi-fi display state should be MM_WFD_SINK_STATE_NULL. \n
+ *
+ * @par Example
+ * @code
+if (mm_wfd_sink_set_display_surface_type(g_wfd_sink, g_display_surface_type) != MM_ERROR_NONE)
+{
+       wfd_sink_error("failed to set display surface type for wi-fi display sink\n");
+}
+ * @endcode
+ */
+int mm_wfd_sink_set_display_surface_type(MMHandleType wfd_sink, gint display_surface_type);
+
+/**
+ * This function sets the display overlay for wi-fi display sink\n
+ *
+ * @param      wfd_sink                [in]    Handle of wi-fi display sink
+ * @param      display_overlay         [in]    Display overlay
+ *
+ * @return     This function returns zero on success, or negative value with error code.
+ * @pre                wi-fi display state should be MM_WFD_SINK_STATE_NULL. \n
+ *
+ * @par Example
+ * @code
+if (mm_wfd_sink_set_display_overlay(g_wfd_sink, g_display_overlay) != MM_ERROR_NONE)
+{
+       wfd_sink_error("failed to set display overlay for wi-fi display sink\n");
+}
+ * @endcode
+ */
+int mm_wfd_sink_set_display_overlay(MMHandleType wfd_sink, void *display_overlay);
+
+/**
+ * This function sets the display method for wi-fi display sink\n
+ *
+ * @param      wfd_sink                [in]    Handle of wi-fi display sink
+ * @param      display_method          [in]    Display method
+ *
+ * @return     This function returns zero on success, or negative value with error code.
+ * @pre                wi-fi display state should be MM_WFD_SINK_STATE_NULL. \n
+ *
+ * @par Example
+ * @code
+if (mm_wfd_sink_set_display_method(g_wfd_sink, g_display_method) != MM_ERROR_NONE)
+{
+       wfd_sink_error("failed to set display method for wi-fi display sink\n");
+}
+ * @endcode
+ */
+int mm_wfd_sink_set_display_method(MMHandleType wfd_sink, gint display_method);
+
+/**
+ * This function sets the display visible for wi-fi display sink\n
+ *
+ * @param      wfd_sink                [in]    Handle of wi-fi display sink
+ * @param      display_visible         [in]    Display visible
+ *
+ * @return     This function returns zero on success, or negative value with error code.
+ * @pre                wi-fi display state should be MM_WFD_SINK_STATE_NULL. \n
+ *
+ * @par Example
+ * @code
+if (mm_wfd_sink_set_display_visible(g_wfd_sink, g_display_visible) != MM_ERROR_NONE)
+{
+       wfd_sink_error("failed to set display visible for wi-fi display sink\n");
+}
+ * @endcode
+ */
+int mm_wfd_sink_set_display_visible(MMHandleType wfd_sink, gint display_visible);
+
+/**
+ * This function gets the width and height of video which is played by wi-fi display sink\n
+ *
+ * @param      wfd_sink                [in]    Handle of wi-fi display sink
+ * @param      width           [in]    Width of video
+ * @param      height          [in]    Height of video
+ *
+ * @return     This function returns zero on success, or negative value with error code.
+ * @pre                wi-fi display state should be MM_WFD_SINK_STATE_CONNECTED or MM_WFD_SINK_STATE_PLAYING. \n
+ *
+ * @par Example
+ * @code
+gint g_width=0, g_height=0;
+
+if (mm_wfd_sink_get_video_resolution(g_wfd_sink, &g_width, &g_height) != MM_ERROR_NONE)
+{
+       wfd_sink_error("failed to get video resolution.\n");
+}
+ * @endcode
+ */
+int mm_wfd_sink_get_video_resolution(MMHandleType wfd_sink, gint *width, gint *height);
+
+/**
+ * This function gets the width and height of video which is played by wi-fi display sink\n
+ *
+ * @param      wfd_sink                [in]    Handle of wi-fi display sink
+ * @param      framerate               [in]    Framerate of video
+ *
+ * @return     This function returns zero on success, or negative value with error code.
+ * @pre                wi-fi display state should be MM_WFD_SINK_STATE_CONNECTED or MM_WFD_SINK_STATE_PLAYING. \n
+ *
+ * @par Example
+ * @code
+gint g_framerate=0;
+
+if (mm_wfd_sink_get_video_framerate(g_wfd_sink, &g_framerate) != MM_ERROR_NONE)
+{
+       wfd_sink_error("failed to get video framerate.\n");
+}
+ * @endcode
+ */
+int mm_wfd_sink_get_video_framerate(MMHandleType wfd_sink,  gint *framerate);
+
+/**
+ * This function sets the resolutions for wi-fi display sink\n
+ *
+ * @param      wfd_sink                [in]    Handle of wi-fi display sink
+ * @param      resolution              [in]    Resolutions for wi-fi display sink
+ *
+ * @return     This function returns zero on success, or negative value with error code.
+ * @pre                wi-fi display state should be MM_WFD_SINK_STATE_NULL. \n
+ *
+ */
+int mm_wfd_sink_set_resolution(MMHandleType wfd_sink,  gint resolution);
+
+int mm_wfd_sink_get_negotiated_video_codec(MMHandleType wfd_sink,  gint *codec);
+int mm_wfd_sink_get_negotiated_video_resolution(MMHandleType wfd_sink,  gint *width, gint *height);
+int mm_wfd_sink_get_negotiated_video_frame_rate(MMHandleType wfd_sink,  gint *frame_rate);
+int mm_wfd_sink_get_negotiated_audio_codec(MMHandleType wfd_sink,  gint *codec);
+int mm_wfd_sink_get_negotiated_audio_channel(MMHandleType wfd_sink,  gint *channel);
+int mm_wfd_sink_get_negotiated_audio_sample_rate(MMHandleType wfd_sink,  gint *sample_rate);
+int mm_wfd_sink_get_negotiated_audio_bitwidth(MMHandleType wfd_sink,  gint *bitwidth);
+#endif
diff --git a/src/include/mm_wfd_sink_attrs.h b/src/include/mm_wfd_sink_attrs.h
new file mode 100755 (executable)
index 0000000..1c6fc48
--- /dev/null
@@ -0,0 +1,132 @@
+/*
+ * libmm-wfd
+ *
+ * Copyright (c) 2011 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: JongHyuk Choi <jhchoi.choi@samsung.com>, ByungWook Jang <bw.jang@samsung.com>,
+ * Manoj Kumar K <manojkumar.k@samsung.com>, Hyunil Park <hyunil46.park@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef __MM_WFD_ATTRS_H__
+#define __MM_WFD_ATTRS_H__
+
+#include <string.h>
+#include <glib.h>
+#include <mm_message.h>
+#include <mm_error.h>
+#include <mm_types.h>
+#include <mm_attrs_private.h>
+#include <mm_attrs.h>
+#include <mm_debug.h>
+
+/* general */
+#ifndef ARRAY_SIZE
+#define ARRAY_SIZE(arr)  (sizeof(arr) / sizeof((arr)[0]))
+#endif
+#define MMWFD_MAX_INT (2147483647)
+
+/**
+ * Enumeration for attribute values types.
+ */
+typedef enum {
+       MM_WFD_ATTRS_TYPE_INVALID = -1,        /**< Type is invalid */
+       MM_WFD_ATTRS_TYPE_INT,                 /**< Integer type */
+       MM_WFD_ATTRS_TYPE_DOUBLE,              /**< Double type */
+       MM_WFD_ATTRS_TYPE_STRING,              /**< UTF-8 String type */
+       MM_WFD_ATTRS_TYPE_DATA,                /**< Pointer type */
+       MM_WFD_ATTRS_TYPE_ARRAY,               /**< Array type */
+       MM_WFD_ATTRS_TYPE_RANGE,               /**< Range type */
+       MM_WFD_ATTRS_TYPE_NUM,                 /**< Number of attribute type */
+} MMWfdAttrsType;
+
+/**
+ * Enumeration for attribute validation type.
+ */
+typedef enum {
+       MM_WFD_ATTRS_VALID_TYPE_INVALID = -1,       /**< Invalid validation type */
+       MM_WFD_ATTRS_VALID_TYPE_NONE,               /**< Do not check validity */
+       MM_WFD_ATTRS_VALID_TYPE_INT_ARRAY,          /**< validity checking type of integer array */
+       MM_WFD_ATTRS_VALID_TYPE_INT_RANGE,          /**< validity checking type of integer range */
+       MM_WFD_ATTRS_VALID_TYPE_DOUBLE_ARRAY,       /**< validity checking type of double array */
+       MM_WFD_ATTRS_VALID_TYPE_DOUBLE_RANGE,       /**< validity checking type of double range */
+} MMWfdAttrsValidType;
+
+/**
+ * Enumeration for attribute access flag.
+ */
+typedef enum {
+       MM_WFD_ATTRS_FLAG_NONE = 0,              /**< None flag is set */
+       MM_WFD_ATTRS_FLAG_READABLE = 1 << 0,     /**< Readable */
+       MM_WFD_ATTRS_FLAG_WRITABLE = 1 << 1,     /**< Writable */
+       MM_WFD_ATTRS_FLAG_MODIFIED = 1 << 2,     /**< Modified */
+
+       MM_WFD_ATTRS_FLAG_RW = MM_WFD_ATTRS_FLAG_READABLE | MM_WFD_ATTRS_FLAG_WRITABLE, /**< Readable and Writable */
+} MMWfdAttrsFlag;
+
+/**
+ * Attribute validity structure
+ */
+typedef struct {
+       MMWfdAttrsType type;
+       MMWfdAttrsValidType validity_type;
+       MMWfdAttrsFlag flag;
+       /**
+         * a union that describes validity of the attribute.
+         * Only when type is 'MM_ATTRS_TYPE_INT' or 'MM_ATTRS_TYPE_DOUBLE',
+         * the attribute can have validity.
+        */
+       union {
+               /**
+                  * Validity structure for integer array.
+                */
+               struct {
+                       int *array;  /**< a pointer of array */
+                       int count;   /**< size of array */
+                       int d_val;
+               } int_array;
+               /**
+                  * Validity structure for integer range.
+                */
+               struct {
+                       int min;   /**< minimum range */
+                       int max;   /**< maximum range */
+                       int d_val;
+               } int_range;
+               /**
+               * Validity structure for double array.
+               */
+               struct {
+                       double    *array;  /**< a pointer of array */
+                       int    count;   /**< size of array */
+                       double d_val;
+               } double_array;
+               /**
+               * Validity structure for double range.
+               */
+               struct {
+                       double   min;   /**< minimum range */
+                       double   max;   /**< maximum range */
+                       double d_val;
+               } double_range;
+       };
+} MMWfdAttrsInfo;
+
+MMHandleType _mmwfd_construct_attribute(MMHandleType hwfd);
+void  _mmwfd_deconstruct_attribute(MMHandleType hwfd);
+int _mmwfd_set_attribute(MMHandleType hwfd,  char **err_atr_name, const char *attribute_name, va_list args_list);
+int _mmwfd_get_attributes_info(MMHandleType handle,  const char *attribute_name, MMWfdAttrsInfo *dst_info);
+int _mmwfd_get_attribute(MMHandleType handle,  char **err_attr_name, const char *attribute_name, va_list args_list);
+#endif /* __MM_WFD_ATTRS_H__ */
\ No newline at end of file
diff --git a/src/include/mm_wfd_sink_dlog.h b/src/include/mm_wfd_sink_dlog.h
new file mode 100755 (executable)
index 0000000..58082e8
--- /dev/null
@@ -0,0 +1,100 @@
+/*
+* 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 FONT_COLOR_RESET    "\033[0m"
+#define FONT_COLOR_RED      "\033[31m"
+#define FONT_COLOR_GREEN    "\033[32m"
+#define FONT_COLOR_YELLOW   "\033[33m"
+#define FONT_COLOR_BLUE     "\033[34m"
+#define FONT_COLOR_PURPLE   "\033[35m"
+#define FONT_COLOR_CYAN     "\033[36m"
+#define FONT_COLOR_GRAY     "\033[37m"
+
+#define wfd_sink_debug(fmt, arg...) do { \
+               LOGD(FONT_COLOR_RESET""fmt"", ##arg);     \
+       } while (0)
+
+#define wfd_sink_info(fmt, arg...) do { \
+               LOGI(FONT_COLOR_GREEN""fmt""FONT_COLOR_RESET, ##arg);     \
+       } while (0)
+
+#define wfd_sink_error(fmt, arg...) do { \
+               LOGE(FONT_COLOR_RED""fmt""FONT_COLOR_RESET, ##arg);     \
+       } while (0)
+
+#define wfd_sink_warning(fmt, arg...) do { \
+               LOGW(FONT_COLOR_YELLOW""fmt""FONT_COLOR_RESET, ##arg);     \
+       } while (0)
+
+#define wfd_sink_debug_fenter() do { \
+               LOGD(FONT_COLOR_RESET"<Enter>");     \
+       } while (0)
+
+#define wfd_sink_debug_fleave() do { \
+               LOGD(FONT_COLOR_RESET"<Leave>");     \
+       } while (0)
+
+#define wfd_sink_error_fenter() do { \
+               LOGE(FONT_COLOR_RED"NO-ERROR : <Enter>"FONT_COLOR_RESET);     \
+       } while (0)
+
+#define wfd_sink_error_fleave() do { \
+               LOGE(FONT_COLOR_RED"NO-ERROR : <Leave>"FONT_COLOR_RESET);     \
+       } while (0)
+
+#define wfd_sink_sucure_info(fmt, arg...) do { \
+               SECURE_LOGI(FONT_COLOR_GREEN""fmt""FONT_COLOR_RESET, ##arg);     \
+       } while (0)
+
+#define wfd_sink_return_if_fail(expr)  \
+       if(!(expr)) {   \
+               wfd_sink_error(FONT_COLOR_RED"failed [%s]\n"FONT_COLOR_RESET, #expr);   \
+               return; \
+       }
+
+#define wfd_sink_return_val_if_fail(expr, val) \
+       if (!(expr)) {  \
+               wfd_sink_error(FONT_COLOR_RED"failed [%s]\n"FONT_COLOR_RESET, #expr);   \
+               return val; \
+       }
+
+#define wfd_sink_assert_not_reached() \
+       { \
+               wfd_sink_error(FONT_COLOR_RED"assert_not_reached()"FONT_COLOR_RESET); \
+               assert(0); \
+       }
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __MM_WFD_SINK_DLOG_H__ */
+
diff --git a/src/include/mm_wfd_sink_enum.h b/src/include/mm_wfd_sink_enum.h
new file mode 100755 (executable)
index 0000000..c88cc8b
--- /dev/null
@@ -0,0 +1,145 @@
+/*
+ * Enumeration for WFD
+ *
+ * Copyright (c) 2011 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: JongHyuk Choi <jhchoi.choi@samsung.com>, ByungWook Jang <bw.jang@samsung.com>,
+ * Maksym Ukhanov <m.ukhanov@samsung.com>, Hyunjun Ko <zzoon.ko@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef _MM_WFD_SINK_WFD_ENUM_H_
+#define _MM_WFD_SINK_WFD_ENUM_H_
+
+typedef enum {
+       WFD_AUDIO_UNKNOWN       = 0,
+       WFD_AUDIO_LPCM          = (1 << 0),
+       WFD_AUDIO_AAC           = (1 << 1),
+       WFD_AUDIO_AC3           = (1 << 2)
+} WFDAudioFormats;
+
+typedef enum {
+       WFD_FREQ_UNKNOWN = 0,
+       WFD_FREQ_44100   = (1 << 0),
+       WFD_FREQ_48000   = (1 << 1)
+} WFDAudioFreq;
+
+typedef enum {
+       WFD_CHANNEL_UNKNOWN = 0,
+       WFD_CHANNEL_2           = (1 << 0),
+       WFD_CHANNEL_4           = (1 << 1),
+       WFD_CHANNEL_6           = (1 << 2),
+       WFD_CHANNEL_8           = (1 << 3)
+} WFDAudioChannels;
+
+
+typedef enum {
+       WFD_VIDEO_UNKNOWN = 0,
+       WFD_VIDEO_H264    = (1 << 0)
+} WFDVideoCodecs;
+
+typedef enum {
+       WFD_VIDEO_CEA_RESOLUTION = 0,
+       WFD_VIDEO_VESA_RESOLUTION,
+       WFD_VIDEO_HH_RESOLUTION
+} WFDVideoNativeResolution;
+
+typedef enum {
+       WFD_CEA_UNKNOWN         = 0,
+       WFD_CEA_640x480P60      = (1 << 0),
+       WFD_CEA_720x480P60      = (1 << 1),
+       WFD_CEA_720x480I60      = (1 << 2),
+       WFD_CEA_720x576P50      = (1 << 3),
+       WFD_CEA_720x576I50      = (1 << 4),
+       WFD_CEA_1280x720P30     = (1 << 5),
+       WFD_CEA_1280x720P60     = (1 << 6),
+       WFD_CEA_1920x1080P30 = (1 << 7),
+       WFD_CEA_1920x1080P60 = (1 << 8),
+       WFD_CEA_1920x1080I60 = (1 << 9),
+       WFD_CEA_1280x720P25     = (1 << 10),
+       WFD_CEA_1280x720P50     = (1 << 11),
+       WFD_CEA_1920x1080P25 = (1 << 12),
+       WFD_CEA_1920x1080P50 = (1 << 13),
+       WFD_CEA_1920x1080I50 = (1 << 14),
+       WFD_CEA_1280x720P24     = (1 << 15),
+       WFD_CEA_1920x1080P24 = (1 << 16)
+} WFDVideoCEAResolution;
+
+typedef enum {
+       WFD_VESA_UNKNOWN                = 0,
+       WFD_VESA_800x600P30     = (1 << 0),
+       WFD_VESA_800x600P60             = (1 << 1),
+       WFD_VESA_1024x768P30    = (1 << 2),
+       WFD_VESA_1024x768P60    = (1 << 3),
+       WFD_VESA_1152x864P30    = (1 << 4),
+       WFD_VESA_1152x864P60    = (1 << 5),
+       WFD_VESA_1280x768P30    = (1 << 6),
+       WFD_VESA_1280x768P60    = (1 << 7),
+       WFD_VESA_1280x800P30    = (1 << 8),
+       WFD_VESA_1280x800P60    = (1 << 9),
+       WFD_VESA_1360x768P30    = (1 << 10),
+       WFD_VESA_1360x768P60    = (1 << 11),
+       WFD_VESA_1366x768P30    = (1 << 12),
+       WFD_VESA_1366x768P60    = (1 << 13),
+       WFD_VESA_1280x1024P30   = (1 << 14),
+       WFD_VESA_1280x1024P60   = (1 << 15),
+       WFD_VESA_1400x1050P30   = (1 << 16),
+       WFD_VESA_1400x1050P60   = (1 << 17),
+       WFD_VESA_1440x900P30    = (1 << 18),
+       WFD_VESA_1440x900P60    = (1 << 19),
+       WFD_VESA_1600x900P30    = (1 << 20),
+       WFD_VESA_1600x900P60    = (1 << 21),
+       WFD_VESA_1600x1200P30   = (1 << 22),
+       WFD_VESA_1600x1200P60   = (1 << 23),
+       WFD_VESA_1680x1024P30   = (1 << 24),
+       WFD_VESA_1680x1024P60   = (1 << 25),
+       WFD_VESA_1680x1050P30   = (1 << 26),
+       WFD_VESA_1680x1050P60   = (1 << 27),
+       WFD_VESA_1920x1200P30   = (1 << 28),
+       WFD_VESA_1920x1200P60   = (1 << 29)
+} WFDVideoVESAResolution;
+
+typedef enum {
+       WFD_HH_UNKNOWN          = 0,
+       WFD_HH_800x480P30       = (1 << 0),
+       WFD_HH_800x480P60       = (1 << 1),
+       WFD_HH_854x480P30       = (1 << 2),
+       WFD_HH_854x480P60       = (1 << 3),
+       WFD_HH_864x480P30       = (1 << 4),
+       WFD_HH_864x480P60       = (1 << 5),
+       WFD_HH_640x360P30       = (1 << 6),
+       WFD_HH_640x360P60       = (1 << 7),
+       WFD_HH_960x540P30       = (1 << 8),
+       WFD_HH_960x540P60       = (1 << 9),
+       WFD_HH_848x480P30       = (1 << 10),
+       WFD_HH_848x480P60       = (1 << 11)
+} WFDVideoHHResolution;
+
+typedef enum {
+       WFD_H264_UNKNOWN_PROFILE = 0,
+       WFD_H264_BASE_PROFILE   = (1 << 0),
+       WFD_H264_HIGH_PROFILE   = (1 << 1)
+} WFDVideoH264Profile;
+
+typedef enum {
+       WFD_H264_LEVEL_UNKNOWN = 0,
+       WFD_H264_LEVEL_3_1   = (1 << 0),
+       WFD_H264_LEVEL_3_2   = (1 << 1),
+       WFD_H264_LEVEL_4       = (1 << 2),
+       WFD_H264_LEVEL_4_1   = (1 << 3),
+       WFD_H264_LEVEL_4_2   = (1 << 4)
+} WFDVideoH264Level;
+
+#endif /*_MM_WFD_SINK_WFD_ENUM_H_*/
diff --git a/src/include/mm_wfd_sink_ini.h b/src/include/mm_wfd_sink_ini.h
new file mode 100755 (executable)
index 0000000..f1122ce
--- /dev/null
@@ -0,0 +1,353 @@
+/*
+ * libmm-wfd
+ *
+ * Copyright (c) 2011 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: JongHyuk Choi <jhchoi.choi@samsung.com>, ByungWook Jang <bw.jang@samsung.com>,
+ * Manoj Kumar K <manojkumar.k@samsung.com>, Hyunil Park <hyunil46.park@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef __MM_WFD_SINK_INI_H__
+#define __MM_WFD_SINK_INI_H__
+
+#include <glib.h>
+#include <tzplatform_config.h>
+#include "mm_wfd_sink_enum.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+enum WFDSinkINIProbeFlags
+{
+       WFD_SINK_INI_PROBE_DEFAULT = 0,
+       WFD_SINK_INI_PROBE_TIMESTAMP = (1 << 0),
+       WFD_SINK_INI_PROBE_BUFFERSIZE = (1 << 1),
+       WFD_SINK_INI_PROBE_CAPS = (1 << 2),
+       WFD_SINK_INI_PROBE_BUFFER_DURATION = (1 << 3),
+};
+
+#define MM_WFD_SINK_INI_DEFAULT_PATH   SYSCONFDIR"/multimedia/mmfw_wfd_sink.ini"
+
+#define WFD_SINK_INI_MAX_STRLEN        256
+#define WFD_SINK_INI_MAX_ELEMENT       10
+
+/* NOTE : MMPlayer has no initalizing API for library itself
+ * so we cannot decide when those ini values to be released.
+ * this is the reason of all string items are static array.
+ * make it do with malloc when MMPlayerInitialize() API created
+ * before that time, we should be careful with size limitation
+ * of each string item.
+ */
+typedef struct __mm_wfd_sink_ini {
+       /* general */
+       gchar gst_param[5][WFD_SINK_INI_MAX_STRLEN];
+       gboolean generate_dot;
+       gboolean enable_pad_probe;
+       gint state_change_timeout;
+       gboolean set_debug_property;
+       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;
+       gboolean enable_wfdsrc_pad_probe;
+
+       /* pipeline */
+       gchar name_of_source[WFD_SINK_INI_MAX_STRLEN];
+       gchar name_of_tsdemux[WFD_SINK_INI_MAX_STRLEN];
+       gchar name_of_audio_hdcp[WFD_SINK_INI_MAX_STRLEN];
+       gchar name_of_aac_parser[WFD_SINK_INI_MAX_STRLEN];
+       gchar name_of_aac_decoder[WFD_SINK_INI_MAX_STRLEN];
+       gchar name_of_ac3_parser[WFD_SINK_INI_MAX_STRLEN];
+       gchar name_of_ac3_decoder[WFD_SINK_INI_MAX_STRLEN];
+       gchar name_of_lpcm_converter[WFD_SINK_INI_MAX_STRLEN];
+       gchar name_of_lpcm_filter[WFD_SINK_INI_MAX_STRLEN];
+       gchar name_of_audio_resampler[WFD_SINK_INI_MAX_STRLEN];
+       gchar name_of_audio_volume[WFD_SINK_INI_MAX_STRLEN];
+       gchar name_of_audio_sink[WFD_SINK_INI_MAX_STRLEN];
+
+       gchar name_of_video_hdcp[WFD_SINK_INI_MAX_STRLEN];
+       gchar name_of_video_parser[WFD_SINK_INI_MAX_STRLEN];
+       gchar name_of_video_capssetter[WFD_SINK_INI_MAX_STRLEN];
+       gchar name_of_video_decoder[WFD_SINK_INI_MAX_STRLEN];
+       gchar name_of_video_converter[WFD_SINK_INI_MAX_STRLEN];
+       gchar name_of_video_filter[WFD_SINK_INI_MAX_STRLEN];
+       gchar name_of_video_sink[WFD_SINK_INI_MAX_STRLEN];
+       gchar name_of_video_evas_sink[WFD_SINK_INI_MAX_STRLEN];
+
+       /* audio parameter for reponse of M3 request */
+       guint audio_codec;
+       guint audio_latency;
+       guint audio_channel;
+       guint audio_sampling_frequency;
+
+       /* video parameter for reponse of M3 request */
+       guint video_codec;
+       guint video_native_resolution;
+       guint video_cea_support;
+       guint video_vesa_support;
+       guint video_hh_support;
+       guint video_profile;
+       guint video_level;
+       guint video_latency;
+       gint video_vertical_resolution;
+       gint video_horizontal_resolution;
+       gint video_minimum_slicing;
+       gint video_slice_enc_param;
+       gint video_framerate_control_support;
+
+       /* hdcp parameter for reponse of M3 request */
+       gint hdcp_content_protection;
+       gint hdcp_port_no;
+} mm_wfd_sink_ini_t;
+
+
+/*Default sink ini values*/
+/* General*/
+#define DEFAULT_GST_PARAM      ""
+#define DEFAULT_GENERATE_DOT   FALSE
+#define DEFAULT_ENABLE_PAD_PROBE       FALSE
+#define DEFAULT_STATE_CHANGE_TIMEOUT 5 /* sec */
+#define DEFAULT_SET_DEBUG_PROPERTY     TRUE
+#define DEFAULT_ENABLE_ASM     FALSE
+#define DEFAULT_JITTER_BUFFER_LATENCY 10 /* msec */
+#define DEFAULT_ENABLE_RETRANSMISSION  FALSE
+#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
+
+/* Pipeline */
+#define DEFAULT_NAME_OF_SOURCE "wfdsrc"
+#define DEFAULT_NAME_OF_TSDEMUX ""
+#define DEFAULT_NAME_OF_AUDIO_HDCP ""
+#define DEFAULT_NAME_OF_AAC_PARSER ""
+#define DEFAULT_NAME_OF_AAC_DECODER ""
+#define DEFAULT_NAME_OF_AC3_PARSER ""
+#define DEFAULT_NAME_OF_AC3_DECODER ""
+#define DEFAULT_NAME_OF_LPCM_CONVERTER ""
+#define DEFAULT_NAME_OF_LPCM_FILTER ""
+#define DEFAULT_NAME_OF_AUDIO_RESAMPLER ""
+#define DEFAULT_NAME_OF_AUDIO_VOLUME ""
+#define DEFAULT_NAME_OF_AUDIO_SPLITTER ""
+#define DEFAULT_NAME_OF_AUDIO_SINK ""
+#define DEFAULT_NAME_OF_VIDEO_HDCP ""
+#define DEFAULT_NAME_OF_VIDEO_PARSER ""
+#define DEFAULT_NAME_OF_VIDEO_CAPSSETTER ""
+#define DEFAULT_NAME_OF_VIDEO_DECODER ""
+#define DEFAULT_NAME_OF_VIDEO_CONVERTER ""
+#define DEFAULT_NAME_OF_VIDEO_FILTER ""
+#define DEFAULT_NAME_OF_VIDEO_SINK ""
+#define DEFAULT_NAME_OF_EVAS_VIDEO_SINK ""
+
+/* Audio */
+#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
+
+/* Video */
+#define DEFAULT_VIDEO_CODEC WFD_VIDEO_H264
+#define DEFAULT_VIDEO_NATIVE_RESOLUTION 0x20
+/* CEA :  WFD_CEA_640x480P60  | WFD_CEA_720x480P60 |WFD_CEA_720x576P50 |WFD_CEA_1280x720P30 |
+       WFD_CEA_1280x720P25 | WFD_CEA_1280x720P24 */
+#define DEFAULT_VIDEO_CEA_SUPPORT 0x84ab
+/* VESA : WFD_VESA_800x600P30 */
+#define DEFAULT_VIDEO_VESA_SUPPORT 0x1
+/* HH : WFD_HH_800x480P30 | WFD_HH_854x480P30 | WFD_HH_864x480P30 | WFD_HH_640x360P30 | WFD_HH_960x540P30 | WFD_HH_848x480P30 */
+#define DEFAULT_VIDEO_HH_SUPPORT 0x555
+#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 720
+#define DEFAULT_VIDEO_HORIZONTAL_RESOLUTION 1280
+#define DEFAULT_VIDEO_MIN_SLICESIZE 0
+#define DEFAULT_VIDEO_SLICE_ENC_PARAM 200
+#define DEFAULT_VIDEO_FRAMERATE_CONTROL 11
+
+/* HDCP */
+#define DEFAULT_HDCP_CONTENT_PROTECTION 0x0
+#define DEFAULT_HDCP_PORT_NO 0
+
+
+#define MM_WFD_SINK_DEFAULT_INI \
+" \
+[general]\n\
+; parameters for initializing gstreamer\n\
+; DEFAULT SET(--gst-debug=2, *wfd*:5)\n\
+gstparam1 = --gst-debug=2, *wfd*:5, *wfdtsdemux:1, *wfdrtpbuffer:1\n\
+gstparam2 =\n\
+gstparam3 =\n\
+gstparam4 =\n\
+gstparam5 =\n\
+\n\
+; generating dot file representing pipeline state\n\
+; do export GST_DEBUG_DUMP_DOT_DIR=[dot file path] in the shell\n\
+generate dot = no\n\
+\n\
+; enable pad probe\n\
+enable pad probe = no\n\
+\n\
+; enable wfdsrc inner pad probe\n\
+enable wfdsrc pad probe = no\n\
+\n\
+; enable ts data dump(eg. /var/tmp/*.ts)\n\
+enable ts data dump = no\n\
+\n\
+; allowed timeout for changing pipeline state\n\
+state change timeout = 5 ; sec\n\
+\n\
+; set debug property to wfdsrc plugin for debugging rtsp message\n\
+set debug property = yes\n\
+\n\
+; for asm function enable = yes, disable = no\n\
+enable asm = no\n\
+\n\
+; 0: default value set by wfdsrc element, other: user define value.\n\
+jitter buffer latency=10\n\
+\n\
+; for retransmission request enable = yes, disable = no\n\
+enable retransmission = no\n\
+\n\
+; for reset basetime, enable = yes, disable = no\n\
+enable reset basetime = yes\n\
+\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\
+wfdsrc element = wfdsrc\n\
+\n\
+tsdemux element = wfdtsdemux\n\
+\n\
+aac parser element = aacparse\n\
+\n\
+aac decoder element = avdec_aac\n\
+\n\
+ac3 parser element = ac3parse\n\
+\n\
+ac3 decoder element =\n\
+\n\
+lpcm converter element =\n\
+\n\
+lpcm filter element = capsfilter\n\
+\n\
+audio resampler element = audioconvert\n\
+\n\
+audio volume element =\n\
+\n\
+audio sink element = pulsesink\n\
+\n\
+video parser element = h264parse\n\
+\n\
+video capssetter element = capssetter\n\
+\n\
+video decoder element = avdec_h264;sprddec_h264;omxh264dec\n\
+\n\
+video converter element =\n\
+\n\
+video filter element =\n\
+\n\
+video sink element = waylandsink;xvimagesink\n\
+\n\
+\n\
+\n\
+[audio param]\n\
+; 0x1: LPCM, 0x2: aac, 0x4: ac3\n\
+;default aac and LPCM\n\
+audio codec=0x3\n\
+\n\
+audio latency=0x0\n\
+\n\
+;0x1 : 48000khz, 0x2: 44100khz\n\
+audio sampling frequency=0x3\n\
+\n\
+; 0x1:2 channels, 0x2:4 channels, 0x4:6channels, 0x8:8channels\n\
+audio channels=0x1\n\
+\n\
+\n\
+\n\
+[video param]\n\
+; 0: H264CBP 1: H264CHP\n\
+video codec=0x1\n\
+\n\
+video native resolution = 0x20\n\
+\n\
+video cea support=0x842b\n\
+\n\
+video vesa support=0x1\n\
+\n\
+video hh support=0x555\n\
+\n\
+; 0x1:base, 0x2:high\n\
+video profile=0x1\n\
+\n\
+; 0x1:level_3_1, 0x2:level_3_2, 0x4:level_4, 0x8:level_4_1, 0x10:level_4_2\n\
+video level=0x2\n\
+\n\
+video latency=0x0\n\
+\n\
+video vertical resolution=720\n\
+\n\
+video horizontal resolution=1280\n\
+\n\
+video minimum slicesize=0\n\
+\n\
+video slice encoding params=200\n\
+\n\
+video framerate control support=11\n\
+\n\
+\n\
+\n\
+[hdcp param]\n\
+;0x0:none, 0x1:HDCP_2.0, 0x2:HDCP_2.1\n\
+hdcp content protection=0x0\n\
+\n\
+hdcp port no=0\n\
+\n\
+"
+
+int
+mm_wfd_sink_ini_load(mm_wfd_sink_ini_t *ini);
+
+int
+mm_wfd_sink_ini_unload(mm_wfd_sink_ini_t *ini);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/src/include/mm_wfd_sink_manager.h b/src/include/mm_wfd_sink_manager.h
new file mode 100755 (executable)
index 0000000..47309e3
--- /dev/null
@@ -0,0 +1,112 @@
+/*
+ * libmm-wfd
+ *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: JongHyuk Choi <jhchoi.choi@samsung.com>, YeJin Cho <cho.yejin@samsung.com>,
+ * Seungbae Shin <seungbae.shin@samsung.com>, YoungHwan An <younghwan_.an@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef __MM_WFD_SINK_MANAGER_H__
+#define __MM_WFD_SINK_MANAGER_H__
+
+/*=======================================================================================
+| INCLUDE FILES                                                                                |
+========================================================================================*/
+#include "mm_wfd_sink_priv.h"
+#include "mm_wfd_sink_util.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#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 {\
+               if (wfd_sink->manager_thread_exit == FALSE) {\
+                       wfd_sink_debug("manager thread is waiting for command signal");\
+                       wfd_sink->waiting_cmd = TRUE; \
+                       g_cond_wait(&((wfd_sink)->manager_thread_cond), &((wfd_sink)->manager_thread_mutex)); \
+                       wfd_sink->waiting_cmd = FALSE; \
+               } else {\
+                       wfd_sink_debug("manager thread is stopped, don't need to wait for command signal");\
+               }\
+       } while (0);
+
+#define WFD_SINK_MANAGER_APPEND_CMD(wfd_sink, cmd) \
+       do {\
+               WFD_SINK_MANAGER_LOCK(wfd_sink);\
+               if (cmd == WFD_SINK_MANAGER_CMD_EXIT) {\
+                       g_list_free(wfd_sink->manager_thread_cmd);\
+                       wfd_sink->manager_thread_cmd = NULL;\
+                       wfd_sink->manager_thread_exit = TRUE;\
+               }\
+               wfd_sink->manager_thread_cmd = g_list_append(wfd_sink->manager_thread_cmd, GINT_TO_POINTER(cmd)); \
+               WFD_SINK_MANAGER_UNLOCK(wfd_sink);\
+       } while (0);
+
+#define WFD_SINK_MANAGER_SIGNAL_CMD(wfd_sink) \
+       do {\
+               WFD_SINK_MANAGER_LOCK(wfd_sink);\
+               if (wfd_sink->waiting_cmd) {\
+                       if (wfd_sink->manager_thread_cmd) {\
+                               wfd_sink_debug("send command signal to manager thread");\
+                               g_cond_signal(&((wfd_sink)->manager_thread_cond));\
+                       }\
+               }\
+               WFD_SINK_MANAGER_UNLOCK(wfd_sink);\
+       } while (0);
+
+/**
+ * This function is to initialize manager
+ *
+ * @param[in]  handle          Handle of wfd_sink.
+ * @return     This function returns zero on success, or negative value with errors.
+ * @remarks
+ * @see
+ *
+ */
+int _mm_wfd_sink_init_manager(mm_wfd_sink_t *wfd_sink);
+/**
+ * This function is to release manager
+ *
+ * @param[in]  handle          Handle of wfd_sink.
+ * @return     This function returns zero on success, or negative value with errors.
+ * @remarks
+ * @see
+ *
+ */
+int _mm_wfd_sink_release_manager(mm_wfd_sink_t *wfd_sink);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/src/include/mm_wfd_sink_priv.h b/src/include/mm_wfd_sink_priv.h
new file mode 100755 (executable)
index 0000000..2a0d20b
--- /dev/null
@@ -0,0 +1,248 @@
+/*
+ * libmm-wfd
+ *
+ * Copyright (c) 2011 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: JongHyuk Choi <jhchoi.choi@samsung.com>, ByungWook Jang <bw.jang@samsung.com>,
+ * Maksym Ukhanov <m.ukhanov@samsung.com>, Hyunjun Ko <zzoon.ko@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef _MM_WFD_SINK_PRIV_H_
+#define _MM_WFD_SINK_PRIV_H_
+
+#include <string.h>
+#include <stdlib.h>
+#include <glib.h>
+#include <gst/gst.h>
+#include <mm_types.h>
+#include <mm_attrs.h>
+#include <mm_message.h>
+#include <mm_error.h>
+#include <mm_types.h>
+
+#include "mm_wfd_sink_ini.h"
+#include "mm_wfd_sink_attrs.h"
+#include "mm_wfd_sink.h"
+
+/* main pipeline's element id */
+enum WFDSinkMainElementID {
+       WFD_SINK_M_PIPE = 0, /* NOTE : WFD_SINK_M_PIPE should be zero */
+       WFD_SINK_M_SRC,
+       WFD_SINK_M_DEPAY,
+       WFD_SINK_M_DEMUX,
+       WFD_SINK_M_NUM
+};
+
+/* audio decodebin's element id */
+enum WFDSinkAudioDecodeBinElementID {
+       WFD_SINK_A_D_BIN = 0, /* NOTE : WFD_SINK_A_D_BIN should be zero */
+       WFD_SINK_A_D_QUEUE,
+       WFD_SINK_A_D_HDCP,
+       WFD_SINK_A_D_AAC_PARSE,
+       WFD_SINK_A_D_AAC_DEC,
+       WFD_SINK_A_D_AC3_PARSE,
+       WFD_SINK_A_D_AC3_DEC,
+       WFD_SINK_A_D_LPCM_CONVERTER,
+       WFD_SINK_A_D_LPCM_FILTER,
+       WFD_SINK_A_D_NUM
+};
+
+/* audio sinkbin's element id */
+enum WFDSinkAudioSinkBinElementID {
+       WFD_SINK_A_S_BIN = 0, /* NOTE : WFD_SINK_A_S_BIN should be zero */
+       WFD_SINK_A_S_RESAMPLER,
+       WFD_SINK_A_S_VOLUME,
+       WFD_SINK_A_S_SINK,
+       WFD_SINK_A_S_NUM
+};
+
+/* video decodebin's element id */
+enum WFDSinkVideoDecodeBinElementID {
+       WFD_SINK_V_D_BIN = 0, /* NOTE : WFD_SINK_V_D_BIN should be zero */
+       WFD_SINK_V_D_QUEUE,
+       WFD_SINK_V_D_HDCP,
+       WFD_SINK_V_D_PARSE,
+       WFD_SINK_V_D_CAPSSETTER,
+       WFD_SINK_V_D_DEC,
+       WFD_SINK_V_D_NUM
+};
+
+/* video sinkbin's element id */
+enum WFDSinkVideoSinkBinElementID {
+       WFD_SINK_V_S_BIN = 0, /* NOTE : WFD_SINK_V_S_BIN should be zero */
+       WFD_SINK_V_S_CONVERT,
+       WFD_SINK_V_S_FILTER,
+       WFD_SINK_V_S_SINK,
+       WFD_SINK_V_S_NUM
+};
+
+/**
+ *  * Enumerations of wifi-display command.
+ *   */
+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_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_PAUSE,       /**< command for pausing wifi-display sink  */
+       MM_WFD_SINK_COMMAND_RESUME,      /**< command for resuming 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;
+
+/**
+ *  * Enumerations of thread command.
+ *   */
+typedef enum {
+       WFD_SINK_MANAGER_CMD_NONE = 0,
+       WFD_SINK_MANAGER_CMD_LINK_A_DECODEBIN,
+       WFD_SINK_MANAGER_CMD_LINK_V_DECODEBIN,
+       WFD_SINK_MANAGER_CMD_PREPARE_A_PIPELINE,
+       WFD_SINK_MANAGER_CMD_PREPARE_V_PIPELINE,
+       WFD_SINK_MANAGER_CMD_EXIT,
+} WFDSinkManagerCMDType;
+
+/**
+ *  * Enumerations of resolution.
+ *   */
+typedef enum {
+       MM_WFD_SINK_RESOLUTION_UNKNOWN = 0,
+       MM_WFD_SINK_RESOLUTION_1920x1080_P30 = (1 << 0),  /**< W-1920, H-1080, 30 fps*/
+       MM_WFD_SINK_RESOLUTION_1280x720_P30 = (1 << 1),   /**< W-1280, H-720, 30 fps*/
+       MM_WFD_SINK_RESOLUTION_960x540_P30 = (1 << 2),    /**< W-960, H-540, 30 fps*/
+       MM_WFD_SINK_RESOLUTION_864x480_P30 = (1 << 3),    /**< W-864, H-480, 30 fps*/
+       MM_WFD_SINK_RESOLUTION_720x480_P60 = (1 << 4),    /**< W-720, H-480, 30 fps*/
+       MM_WFD_SINK_RESOLUTION_640x480_P60 = (1 << 5),    /**< W-640, H-480, 60 fps*/
+       MM_WFD_SINK_RESOLUTION_640x360_P30 = (1 << 6),    /**< W-640, H-360, 30 fps*/
+       MM_WFD_SINK_RESOLUTION_MAX = 128,
+} MMWFDSinkResolution;
+
+typedef struct {
+       gint codec;
+       gint width;
+       gint height;
+       gint frame_rate;
+} MMWFDSinkVideoStreamInfo;
+
+typedef struct {
+       gint codec;
+       gint channels;
+       gint sample_rate;
+       gint bitwidth;
+} MMWFDSinkAudioStreamInfo;
+
+typedef struct {
+       MMWFDSinkAudioStreamInfo audio_stream_info;
+       MMWFDSinkVideoStreamInfo video_stream_info;
+} MMWFDSinkStreamInfo;
+
+
+typedef struct {
+       gint id;
+       GstElement *gst;
+} MMWFDSinkGstElement;
+
+typedef struct {
+       MMWFDSinkGstElement     *mainbin;
+       MMWFDSinkGstElement     *a_decodebin;
+       MMWFDSinkGstElement     *v_decodebin;
+       MMWFDSinkGstElement     *a_sinkbin;
+       MMWFDSinkGstElement     *v_sinkbin;
+} MMWFDSinkGstPipelineInfo;
+
+typedef struct {
+       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)
+
+typedef struct {
+       /* gstreamer pipeline */
+       MMWFDSinkGstPipelineInfo *pipeline;
+       gboolean audio_decodebin_is_linked;
+       gboolean video_decodebin_is_linked;
+
+       /* 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;
+
+       /* state */
+       MMWFDSinkState state;
+
+       /* initialize values */
+       mm_wfd_sink_ini_t ini;
+
+       /* command */
+       MMWFDSinkCommandType cmd;
+       GMutex cmd_lock;
+       gboolean waiting_cmd;
+
+       /* stream information */
+       MMWFDSinkStreamInfo stream_info;
+
+       /* Message handling */
+       MMWFDMessageCallback msg_cb;
+       void *msg_user_data;
+
+       /* video resolution for negotiation */
+       MMWFDSinkResolution supportive_resolution;
+
+       GThread         *manager_thread;
+       GMutex manager_thread_mutex;
+       GCond manager_thread_cond;
+       GList *manager_thread_cmd;
+       gboolean manager_thread_exit;
+} mm_wfd_sink_t;
+
+
+int _mm_wfd_sink_create(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_pause(mm_wfd_sink_t *wfd_sink);
+int _mm_wfd_sink_resume(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);
+int _mm_wfd_sink_set_resolution(mm_wfd_sink_t *wfd_sink, MMWFDSinkResolution resolution);
+
+int __mm_wfd_sink_link_audio_decodebin(mm_wfd_sink_t *wfd_sink);
+int __mm_wfd_sink_link_video_decodebin(mm_wfd_sink_t *wfd_sink);
+int __mm_wfd_sink_prepare_video_pipeline(mm_wfd_sink_t *wfd_sink);
+int __mm_wfd_sink_prepare_audio_pipeline(mm_wfd_sink_t *wfd_sink);
+
+const gchar *_mm_wfds_sink_get_state_name(MMWFDSinkStateType state);
+
+#endif
+
diff --git a/src/include/mm_wfd_sink_util.h b/src/include/mm_wfd_sink_util.h
new file mode 100755 (executable)
index 0000000..870982a
--- /dev/null
@@ -0,0 +1,130 @@
+/*
+ * libmm-wfd
+ *
+ * Copyright (c) 2011 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: JongHyuk Choi <jhchoi.choi@samsung.com>, ByungWook Jang <bw.jang@samsung.com>,
+ * Maksym Ukhanov <m.ukhanov@samsung.com>, Hyunjun Ko <zzoon.ko@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef _MM_WFD_SINK_UTIL_H_
+#define _MM_WFD_SINK_UTIL_H_
+
+#include <glib.h>
+#include <gst/gst.h>
+#include <mm_message.h>
+#include <mm_error.h>
+#include <mm_types.h>
+#include "mm_wfd_sink_dlog.h"
+
+#define MMWFDSINK_FREEIF(x) \
+       do      {\
+               if ((x)) \
+                       g_free((gpointer)(x)); \
+               (x) = NULL;\
+       } while (0);
+
+/* lock for commnad */
+#define MMWFDSINK_CMD_LOCK(x_wfd) \
+       if (x_wfd) \
+               g_mutex_lock(&(((mm_wfd_sink_t *)x_wfd)->cmd_lock));
+
+#define MMWFDSINK_CMD_UNLOCK(x_wfd) \
+       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) \
+       do      { \
+               if (x_name && (strlen(x_factory) > 1)) {\
+                       x_bin[x_id].id = x_id;\
+                       x_bin[x_id].gst = gst_element_factory_make(x_factory, x_name);\
+                       if (! x_bin[x_id].gst)  {\
+                               wfd_sink_error("failed to create %s \n", x_factory);\
+                               goto CREATE_ERROR;\
+                       }\
+                       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 MMWFDSINK_GENERATE_DOT_IF_ENABLED(x_wfd_sink, x_name) \
+       if (x_wfd_sink->ini.generate_dot) { \
+               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); \
+       }
+
+/* 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
+#define MMWFDSINK_PENDING_STATE(x_wfd_sink) ((mm_wfd_sink_t *)x_wfd_sink)->state.pending_state
+#define MMWFDSINK_STATE_GET_NAME(x_state) _mm_wfds_sink_get_state_name(x_state)
+
+#define MMWFDSINK_PRINT_STATE(x_wfd_sink) \
+       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)));
+
+#define MMWFDSINK_CHECK_STATE(x_wfd_sink, x_cmd) \
+       switch (__mm_wfd_sink_check_state((mm_wfd_sink_t *)x_wfd_sink, x_cmd)) \
+       { \
+       case MM_ERROR_NONE: \
+               break;\
+       case MM_ERROR_WFD_NO_OP: \
+               return MM_ERROR_NONE; \
+               break; \
+       default: \
+               return MM_ERROR_WFD_INVALID_STATE; \
+               break; \
+       }
+
+
+/* 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) {  \
+               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
+mm_wfd_sink_util_add_pad_probe_for_data_dump(GstElement *element, const gchar *pad_name);
+
+#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); \
+       }
+
+#endif
diff --git a/src/include/mm_wfd_sink_wayland.h b/src/include/mm_wfd_sink_wayland.h
new file mode 100755 (executable)
index 0000000..d3e6da6
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+* 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_WLCLIENT_H__
+#define __MM_WFD_SINK_WLCLIENT_H__
+#include <stdio.h>
+#include <tbm_bufmgr.h>
+#include <tizen-extension-client-protocol.h>
+#include <wayland-client.h>
+#include <mm_types.h>
+#include <mm_debug.h>
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+typedef struct
+{
+       struct wl_display *display;
+       struct wl_registry *registry;
+       struct tizen_surface *tz_surface;
+       struct tizen_resource *tz_resource;
+} wl_client;
+
+int mm_wfd_sink_wlclient_create (wl_client ** wlclient);
+int mm_wfd_sink_wlclient_get_wl_window_wl_surface_id (wl_client * wlclient, struct wl_surface *surface, struct wl_display *display);
+void mm_wfd_sink_wlclient_finalize (wl_client * wlclient);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif                          /* __MM_WFD_SINK_WLCLIENT_H__ */
diff --git a/src/mm_wfd_sink.c b/src/mm_wfd_sink.c
new file mode 100755 (executable)
index 0000000..fd0d335
--- /dev/null
@@ -0,0 +1,450 @@
+/*
+ * libmm-wfd
+ *
+ * Copyright (c) 2011 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: JongHyuk Choi <jhchoi.choi@samsung.com>, ByungWook Jang <bw.jang@samsung.com>,
+ * Maksym Ukhanov <m.ukhanov@samsung.com>, Hyunjun Ko <zzoon.ko@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <gst/gst.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;
+
+       wfd_sink_debug_fenter();
+
+       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) {
+               wfd_sink_error("fail to create wi-fi display sink handle. ret[%d]", result);
+               *wfd_sink = (MMHandleType)NULL;
+               return result;
+       }
+
+       /* init wfd lock */
+       g_mutex_init(&new_wfd_sink->cmd_lock);
+
+       *wfd_sink = (MMHandleType)new_wfd_sink;
+
+       wfd_sink_debug_fleave();
+
+       return result;
+
+}
+
+int mm_wfd_sink_prepare(MMHandleType wfd_sink)
+{
+       int result = MM_ERROR_NONE;
+
+       wfd_sink_return_val_if_fail(wfd_sink, MM_ERROR_WFD_NOT_INITIALIZED);
+
+       MMWFDSINK_CMD_LOCK(wfd_sink);
+       result = _mm_wfd_sink_prepare((mm_wfd_sink_t *)wfd_sink);
+       MMWFDSINK_CMD_UNLOCK(wfd_sink);
+
+       return result;
+}
+
+int mm_wfd_sink_connect(MMHandleType wfd_sink, const char *uri)
+{
+       int result = MM_ERROR_NONE;
+
+       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);
+       MMWFDSINK_CMD_UNLOCK(wfd_sink);
+
+       return result;
+}
+
+int mm_wfd_sink_start(MMHandleType wfd_sink)
+{
+       int result = MM_ERROR_NONE;
+
+       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);
+       MMWFDSINK_CMD_UNLOCK(wfd_sink);
+
+       return result;
+}
+
+int mm_wfd_sink_pause(MMHandleType wfd_sink)
+{
+       int result = MM_ERROR_NONE;
+
+       wfd_sink_return_val_if_fail(wfd_sink, MM_ERROR_WFD_NOT_INITIALIZED);
+
+       MMWFDSINK_CMD_LOCK(wfd_sink);
+       result = _mm_wfd_sink_pause((mm_wfd_sink_t *)wfd_sink);
+       MMWFDSINK_CMD_UNLOCK(wfd_sink);
+
+       return result;
+}
+
+int mm_wfd_sink_resume(MMHandleType wfd_sink)
+{
+       int result = MM_ERROR_NONE;
+
+       wfd_sink_return_val_if_fail(wfd_sink, MM_ERROR_WFD_NOT_INITIALIZED);
+
+       MMWFDSINK_CMD_LOCK(wfd_sink);
+       result = _mm_wfd_sink_resume((mm_wfd_sink_t *)wfd_sink);
+       MMWFDSINK_CMD_UNLOCK(wfd_sink);
+
+       return result;
+}
+
+int mm_wfd_sink_disconnect(MMHandleType wfd_sink)
+{
+       int result = MM_ERROR_NONE;
+
+       wfd_sink_return_val_if_fail(wfd_sink, MM_ERROR_WFD_NOT_INITIALIZED);
+
+       MMWFDSINK_CMD_LOCK(wfd_sink);
+       result = _mm_wfd_sink_disconnect((mm_wfd_sink_t *)wfd_sink);
+       MMWFDSINK_CMD_UNLOCK(wfd_sink);
+
+       return result;
+}
+
+int mm_wfd_sink_unprepare(MMHandleType wfd_sink)
+{
+       int result = MM_ERROR_NONE;
+
+       wfd_sink_return_val_if_fail(wfd_sink, MM_ERROR_WFD_NOT_INITIALIZED);
+
+       MMWFDSINK_CMD_LOCK(wfd_sink);
+       result = _mm_wfd_sink_unprepare((mm_wfd_sink_t *)wfd_sink);
+       MMWFDSINK_CMD_UNLOCK(wfd_sink);
+
+       return result;
+}
+
+int mm_wfd_sink_destroy(MMHandleType wfd_sink)
+{
+       int result = MM_ERROR_NONE;
+       mm_wfd_sink_t *sink_handle = NULL;
+
+       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);
+
+       g_mutex_clear(&(((mm_wfd_sink_t *)wfd_sink)->cmd_lock));
+
+       sink_handle = (mm_wfd_sink_t *)wfd_sink;
+       MMWFDSINK_FREEIF(sink_handle);
+
+       return result;
+}
+
+int mm_wfd_sink_set_message_callback(MMHandleType wfd_sink, MMWFDMessageCallback callback, void *user_data)
+{
+       int result = MM_ERROR_NONE;
+
+       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);
+       MMWFDSINK_CMD_UNLOCK(wfd_sink);
+
+       return result;
+}
+
+int mm_wfd_sink_set_attribute(MMHandleType wfd_sink,  char **err_attr_name, const char *first_attribute_name, ...)
+{
+       int result = MM_ERROR_NONE;
+       va_list var_args;
+
+       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);
+       result = _mmwfd_set_attribute(MMWFDSINK_GET_ATTRS(wfd_sink), err_attr_name, first_attribute_name, var_args);
+       va_end(var_args);
+       MMWFDSINK_CMD_UNLOCK(wfd_sink);
+
+       return result;
+}
+
+int mm_wfd_sink_get_video_resolution(MMHandleType wfd_sink, gint *width, gint *height)
+{
+       mm_wfd_sink_t *wfd = (mm_wfd_sink_t *)wfd_sink;
+
+       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;
+
+       return MM_ERROR_NONE;
+}
+
+int mm_wfd_sink_get_video_framerate(MMHandleType wfd_sink, gint *frame_rate)
+{
+       mm_wfd_sink_t *wfd = (mm_wfd_sink_t *)wfd_sink;
+
+       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;
+
+       return MM_ERROR_NONE;
+}
+
+int mm_wfd_sink_set_resolution(MMHandleType wfd_sink,  gint resolution)
+{
+       int result = MM_ERROR_NONE;
+
+       wfd_sink_return_val_if_fail(wfd_sink, MM_ERROR_WFD_NOT_INITIALIZED);
+       MMWFDSINK_CMD_LOCK(wfd_sink);
+       result = _mm_wfd_sink_set_resolution((mm_wfd_sink_t *)wfd_sink, resolution);
+       MMWFDSINK_CMD_UNLOCK(wfd_sink);
+
+       return result;
+}
+
+int mm_wfd_sink_get_negotiated_video_codec(MMHandleType wfd_sink,  gint *codec)
+{
+       int result = MM_ERROR_NONE;
+       mm_wfd_sink_t *wfd = (mm_wfd_sink_t *)wfd_sink;
+       MMWFDSinkStateType cur_state = MM_WFD_SINK_STATE_NONE;
+
+       wfd_sink_return_val_if_fail(wfd, MM_ERROR_WFD_NOT_INITIALIZED);
+       wfd_sink_return_val_if_fail(codec, MM_ERROR_WFD_INVALID_ARGUMENT);
+
+       MMWFDSINK_CMD_LOCK(wfd);
+
+       MMWFDSINK_PRINT_STATE(wfd);
+       cur_state = MMWFDSINK_CURRENT_STATE(wfd);
+       if (cur_state != MM_WFD_SINK_STATE_CONNECTED &&
+               cur_state != MM_WFD_SINK_STATE_PLAYING &&
+               cur_state != MM_WFD_SINK_STATE_PAUSED) {
+
+               wfd_sink_error("This function must be called after MM_WFD_SINK_STATE_CONNECTED");
+               result = MM_ERROR_WFD_INVALID_STATE;
+       } else {
+               *codec = wfd->stream_info.video_stream_info.codec;
+       }
+
+       MMWFDSINK_CMD_UNLOCK(wfd);
+
+       wfd_sink_debug_fleave();
+
+       return result;
+}
+
+int mm_wfd_sink_get_negotiated_video_resolution(MMHandleType wfd_sink,  gint *width, gint *height)
+{
+       int result = MM_ERROR_NONE;
+       mm_wfd_sink_t *wfd = (mm_wfd_sink_t *)wfd_sink;
+       MMWFDSinkStateType cur_state = MM_WFD_SINK_STATE_NONE;
+
+       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);
+
+       MMWFDSINK_CMD_LOCK(wfd);
+
+       MMWFDSINK_PRINT_STATE(wfd);
+       cur_state = MMWFDSINK_CURRENT_STATE(wfd);
+       if (cur_state != MM_WFD_SINK_STATE_CONNECTED &&
+               cur_state != MM_WFD_SINK_STATE_PLAYING &&
+               cur_state != MM_WFD_SINK_STATE_PAUSED) {
+
+               wfd_sink_error("This function must be called after MM_WFD_SINK_STATE_CONNECTED");
+               result = MM_ERROR_WFD_INVALID_STATE;
+       } else {
+               *width = wfd->stream_info.video_stream_info.width;
+               *height = wfd->stream_info.video_stream_info.height;
+       }
+
+       MMWFDSINK_CMD_UNLOCK(wfd);
+
+       wfd_sink_debug_fleave();
+
+       return result;
+}
+
+int mm_wfd_sink_get_negotiated_video_frame_rate(MMHandleType wfd_sink,  gint *frame_rate)
+{
+       int result = MM_ERROR_NONE;
+       mm_wfd_sink_t *wfd = (mm_wfd_sink_t *)wfd_sink;
+       MMWFDSinkStateType cur_state = MM_WFD_SINK_STATE_NONE;
+
+       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);
+
+       MMWFDSINK_CMD_LOCK(wfd);
+
+       MMWFDSINK_PRINT_STATE(wfd);
+       cur_state = MMWFDSINK_CURRENT_STATE(wfd);
+       if (cur_state != MM_WFD_SINK_STATE_CONNECTED &&
+               cur_state != MM_WFD_SINK_STATE_PLAYING &&
+               cur_state != MM_WFD_SINK_STATE_PAUSED) {
+
+               wfd_sink_error("This function must be called after MM_WFD_SINK_STATE_CONNECTED");
+               result = MM_ERROR_WFD_INVALID_STATE;
+       } else {
+               *frame_rate = wfd->stream_info.video_stream_info.frame_rate;
+       }
+
+       MMWFDSINK_CMD_UNLOCK(wfd);
+
+       wfd_sink_debug_fleave();
+
+       return result;
+}
+
+int mm_wfd_sink_get_negotiated_audio_codec(MMHandleType wfd_sink,  gint *codec)
+{
+       int result = MM_ERROR_NONE;
+       mm_wfd_sink_t *wfd = (mm_wfd_sink_t *)wfd_sink;
+       MMWFDSinkStateType cur_state = MM_WFD_SINK_STATE_NONE;
+
+       wfd_sink_return_val_if_fail(wfd, MM_ERROR_WFD_NOT_INITIALIZED);
+       wfd_sink_return_val_if_fail(codec, MM_ERROR_WFD_INVALID_ARGUMENT);
+
+       MMWFDSINK_CMD_LOCK(wfd);
+
+       MMWFDSINK_PRINT_STATE(wfd);
+       cur_state = MMWFDSINK_CURRENT_STATE(wfd);
+       if (cur_state != MM_WFD_SINK_STATE_CONNECTED &&
+               cur_state != MM_WFD_SINK_STATE_PLAYING &&
+               cur_state != MM_WFD_SINK_STATE_PAUSED) {
+
+               wfd_sink_error("This function must be called after MM_WFD_SINK_STATE_CONNECTED");
+               result = MM_ERROR_WFD_INVALID_STATE;
+       } else {
+               *codec = wfd->stream_info.audio_stream_info.codec;
+       }
+
+       MMWFDSINK_CMD_UNLOCK(wfd);
+
+       wfd_sink_debug_fleave();
+
+       return result;
+}
+
+int mm_wfd_sink_get_negotiated_audio_channel(MMHandleType wfd_sink,  gint *channel)
+{
+       int result = MM_ERROR_NONE;
+       mm_wfd_sink_t *wfd = (mm_wfd_sink_t *)wfd_sink;
+       MMWFDSinkStateType cur_state = MM_WFD_SINK_STATE_NONE;
+
+       wfd_sink_return_val_if_fail(wfd, MM_ERROR_WFD_NOT_INITIALIZED);
+       wfd_sink_return_val_if_fail(channel, MM_ERROR_WFD_INVALID_ARGUMENT);
+
+       MMWFDSINK_CMD_LOCK(wfd);
+
+       MMWFDSINK_PRINT_STATE(wfd);
+       cur_state = MMWFDSINK_CURRENT_STATE(wfd);
+       if (cur_state != MM_WFD_SINK_STATE_CONNECTED &&
+               cur_state != MM_WFD_SINK_STATE_PLAYING &&
+               cur_state != MM_WFD_SINK_STATE_PAUSED) {
+
+               wfd_sink_error("This function must be called after MM_WFD_SINK_STATE_CONNECTED");
+               result = MM_ERROR_WFD_INVALID_STATE;
+       } else {
+               *channel = wfd->stream_info.audio_stream_info.channels;
+       }
+
+       MMWFDSINK_CMD_UNLOCK(wfd);
+
+       wfd_sink_debug_fleave();
+
+       return result;
+}
+
+int mm_wfd_sink_get_negotiated_audio_sample_rate(MMHandleType wfd_sink,  gint *sample_rate)
+{
+       int result = MM_ERROR_NONE;
+       mm_wfd_sink_t *wfd = (mm_wfd_sink_t *)wfd_sink;
+       MMWFDSinkStateType cur_state = MM_WFD_SINK_STATE_NONE;
+
+       wfd_sink_debug_fenter();
+
+       wfd_sink_return_val_if_fail(wfd, MM_ERROR_WFD_NOT_INITIALIZED);
+       wfd_sink_return_val_if_fail(sample_rate, MM_ERROR_WFD_INVALID_ARGUMENT);
+
+       MMWFDSINK_CMD_LOCK(wfd);
+
+       MMWFDSINK_PRINT_STATE(wfd);
+       cur_state = MMWFDSINK_CURRENT_STATE(wfd);
+       if (cur_state != MM_WFD_SINK_STATE_CONNECTED &&
+               cur_state != MM_WFD_SINK_STATE_PLAYING &&
+               cur_state != MM_WFD_SINK_STATE_PAUSED) {
+
+               wfd_sink_error("This function must be called after MM_WFD_SINK_STATE_CONNECTED");
+               result = MM_ERROR_WFD_INVALID_STATE;
+       } else {
+               *sample_rate = wfd->stream_info.audio_stream_info.sample_rate;
+       }
+
+       MMWFDSINK_CMD_UNLOCK(wfd);
+
+       wfd_sink_debug_fleave();
+
+       return result;
+}
+
+int mm_wfd_sink_get_negotiated_audio_bitwidth(MMHandleType wfd_sink,  gint *bitwidth)
+{
+       int result = MM_ERROR_NONE;
+       mm_wfd_sink_t *wfd = (mm_wfd_sink_t *)wfd_sink;
+       MMWFDSinkStateType cur_state = MM_WFD_SINK_STATE_NONE;
+
+       wfd_sink_debug_fenter();
+
+       wfd_sink_return_val_if_fail(wfd, MM_ERROR_WFD_NOT_INITIALIZED);
+       wfd_sink_return_val_if_fail(bitwidth, MM_ERROR_WFD_INVALID_ARGUMENT);
+
+       MMWFDSINK_CMD_LOCK(wfd);
+
+       MMWFDSINK_PRINT_STATE(wfd);
+       cur_state = MMWFDSINK_CURRENT_STATE(wfd);
+       if (cur_state != MM_WFD_SINK_STATE_CONNECTED &&
+               cur_state != MM_WFD_SINK_STATE_PLAYING &&
+               cur_state != MM_WFD_SINK_STATE_PAUSED) {
+
+               wfd_sink_error("This function must be called after MM_WFD_SINK_STATE_CONNECTED");
+               result = MM_ERROR_WFD_INVALID_STATE;
+       } else {
+               *bitwidth = wfd->stream_info.audio_stream_info.bitwidth;
+       }
+
+       MMWFDSINK_CMD_UNLOCK(wfd);
+
+       wfd_sink_debug_fleave();
+
+       return result;
+}
diff --git a/src/mm_wfd_sink_attrs.c b/src/mm_wfd_sink_attrs.c
new file mode 100755 (executable)
index 0000000..e328d6a
--- /dev/null
@@ -0,0 +1,552 @@
+/*
+ * libmm-wfd
+ *
+ * Copyright (c) 2011 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: JongHyuk Choi <jhchoi.choi@samsung.com>, ByungWook Jang <bw.jang@samsung.com>,
+ * Manoj Kumar K <manojkumar.k@samsung.com>, Hyunil Park <hyunil46.park@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include "mm_wfd_sink_attrs.h"
+
+typedef struct {
+       char *name;
+       int value_type;
+       int flags;           /* r, w */
+       void *default_value;
+       int valid_type;
+       int value_min;
+       int value_max;
+} MMWfdAttrsSpec;
+
+/*static gboolean __mmwfd_apply_attribute(MMHandleType handle, const char *attribute_name); */
+
+MMHandleType
+_mmwfd_construct_attribute(MMHandleType handle)
+{
+       int idx = 0;
+       MMHandleType attrs = 0;
+       int num_of_attrs = 0;
+       mmf_attrs_construct_info_t *base = NULL;
+
+       debug_fenter();
+
+       return_val_if_fail(handle, (MMHandleType) NULL);
+
+       MMWfdAttrsSpec wfd_attrs[] = {
+               {
+                       (char *)"server_ip",
+                       MM_ATTRS_TYPE_STRING,
+                       MM_ATTRS_FLAG_RW,
+                       (void *)"127.0.0.1",
+                       MM_ATTRS_VALID_TYPE_NONE,
+                       0,
+                       0
+               },
+
+               {
+                       (char *)"server_port",
+                       MM_ATTRS_TYPE_STRING,
+                       MM_ATTRS_FLAG_RW,
+                       (void *)"8554",
+                       MM_ATTRS_VALID_TYPE_NONE,
+                       0,
+                       0
+               },
+
+               {
+                       (char *)"max_client_count",
+                       MM_ATTRS_TYPE_INT,
+                       MM_ATTRS_FLAG_RW,
+                       (void *)1,
+                       MM_ATTRS_VALID_TYPE_INT_RANGE,
+                       0,
+                       10
+               },
+               /* Initialized with invalid native type, if a valid value is set then only this atribute will be considered */
+               {
+                       (char *)"native_resolution",
+                       MM_ATTRS_TYPE_INT,
+                       MM_ATTRS_FLAG_RW,
+                       (void *)0,
+                       MM_ATTRS_VALID_TYPE_INT_RANGE,
+                       0,
+                       3
+               },
+               /* Initialized with invalid resolution, if a valid value is set then only this atribute will be considered */
+               {
+                       (char *)"prefered_resolutions",
+                       MM_ATTRS_TYPE_INT,
+                       MM_ATTRS_FLAG_RW,
+                       (void *)2147483647,
+                       MM_ATTRS_VALID_TYPE_INT_RANGE,
+                       0,
+                       2147483647
+               },
+               /* Initialized with invalid uibc option, if a valid value is set then only this atribute will be considered */
+               {
+                       (char *)"set_hdcp",
+                       MM_ATTRS_TYPE_INT,
+                       MM_ATTRS_FLAG_RW,
+                       (void *)2,
+                       MM_ATTRS_VALID_TYPE_INT_RANGE,
+                       0,
+                       2
+               },
+               {
+                       (char *)"display_rotate",
+                       MM_ATTRS_TYPE_INT,
+                       MM_ATTRS_FLAG_RW,
+                       (void *)0,
+                       MM_ATTRS_VALID_TYPE_INT_RANGE,
+                       0,
+                       3
+               },
+               {
+                       (char *)"display_src_crop_x",
+                       MM_ATTRS_TYPE_INT,
+                       MM_ATTRS_FLAG_RW,
+                       (void *) 0,
+                       MM_ATTRS_VALID_TYPE_INT_RANGE,
+                       0,
+                       4096
+               },
+               {
+                       (char *)"display_src_crop_y",
+                       MM_ATTRS_TYPE_INT,
+                       MM_ATTRS_FLAG_RW,
+                       (void *) 0,
+                       MM_ATTRS_VALID_TYPE_INT_RANGE,
+                       0,
+                       4096
+               },
+               {
+                       (char *)"display_src_crop_width",
+                       MM_ATTRS_TYPE_INT,
+                       MM_ATTRS_FLAG_RW,
+                       (void *) 0,
+                       MM_ATTRS_VALID_TYPE_INT_RANGE,
+                       0,
+                       4096
+               },
+               {
+                       (char *)"display_src_crop_height",
+                       MM_ATTRS_TYPE_INT,
+                       MM_ATTRS_FLAG_RW,
+                       (void *) 0,
+                       MM_ATTRS_VALID_TYPE_INT_RANGE,
+                       0,
+                       4096
+               },
+               {
+                       (char *)"display_roi_x",
+                       MM_ATTRS_TYPE_INT,
+                       MM_ATTRS_FLAG_RW,
+                       (void *) 0,
+                       MM_ATTRS_VALID_TYPE_INT_RANGE,
+                       0,
+                       4096
+               },
+               {
+                       (char *)"display_roi_y",
+                       MM_ATTRS_TYPE_INT,
+                       MM_ATTRS_FLAG_RW,
+                       (void *) 0,
+                       MM_ATTRS_VALID_TYPE_INT_RANGE,
+                       0,
+                       4096
+               },
+               {
+                       (char *)"display_roi_width",
+                       MM_ATTRS_TYPE_INT,
+                       MM_ATTRS_FLAG_RW,
+                       (void *) 480,
+                       MM_ATTRS_VALID_TYPE_INT_RANGE,
+                       0,
+                       4096
+               },
+               {
+                       (char *)"display_roi_height",
+                       MM_ATTRS_TYPE_INT,
+                       MM_ATTRS_FLAG_RW,
+                       (void *) 800,
+                       MM_ATTRS_VALID_TYPE_INT_RANGE,
+                       0,
+                       4096
+               },
+               {
+                       (char *)"display_roi_mode",
+                       MM_ATTRS_TYPE_INT,
+                       MM_ATTRS_FLAG_RW,
+                       (void *) MM_DISPLAY_METHOD_CUSTOM_ROI_FULL_SCREEN,
+                       MM_ATTRS_VALID_TYPE_INT_RANGE,
+                       MM_DISPLAY_METHOD_CUSTOM_ROI_FULL_SCREEN,
+                       MM_DISPLAY_METHOD_CUSTOM_ROI_LETER_BOX
+               },
+               {
+                       (char *)"display_rotation",
+                       MM_ATTRS_TYPE_INT,
+                       MM_ATTRS_FLAG_RW,
+                       (void *) MM_DISPLAY_ROTATION_NONE,
+                       MM_ATTRS_VALID_TYPE_INT_RANGE,
+                       MM_DISPLAY_ROTATION_NONE,
+                       MM_DISPLAY_ROTATION_270
+               },
+               {
+                       (char *)"display_visible",
+                       MM_ATTRS_TYPE_INT,
+                       MM_ATTRS_FLAG_RW,
+                       (void *) TRUE,
+                       MM_ATTRS_VALID_TYPE_INT_RANGE,
+                       0,
+                       1
+               },
+               {
+                       (char *)"display_method",
+                       MM_ATTRS_TYPE_INT,
+                       MM_ATTRS_FLAG_RW,
+                       (void *) MM_DISPLAY_METHOD_LETTER_BOX,
+                       MM_ATTRS_VALID_TYPE_INT_RANGE,
+                       MM_DISPLAY_METHOD_LETTER_BOX,
+                       MM_DISPLAY_METHOD_CUSTOM_ROI
+               },
+               {
+                       (char *)"display_overlay",
+                       MM_ATTRS_TYPE_DATA,
+                       MM_ATTRS_FLAG_RW,
+                       (void *) NULL,
+                       MM_ATTRS_VALID_TYPE_NONE,
+                       0,
+                       0
+               },
+               {
+                       (char *)"display_overlay_user_data",
+                       MM_ATTRS_TYPE_DATA,
+                       MM_ATTRS_FLAG_RW,
+                       (void *) NULL,
+                       MM_ATTRS_VALID_TYPE_NONE,
+                       0,
+                       0
+               },
+               {
+                       (char *)"display_zoom",
+                       MM_ATTRS_TYPE_DOUBLE,
+                       MM_ATTRS_FLAG_RW,
+                       (void *) 1,
+                       MM_ATTRS_VALID_TYPE_DOUBLE_RANGE,
+                       1.0,
+                       9.0
+               },
+               {
+                       (char *)"display_surface_type",
+                       MM_ATTRS_TYPE_INT,
+                       MM_ATTRS_FLAG_RW,
+                       (void *) MM_DISPLAY_SURFACE_OVERLAY,
+                       MM_ATTRS_VALID_TYPE_INT_RANGE,
+                       MM_DISPLAY_SURFACE_OVERLAY,
+                       MM_DISPLAY_SURFACE_REMOTE
+               },
+               {
+                       (char *)"display_width",   /* dest width of fimcconvert ouput */
+                       MM_ATTRS_TYPE_INT,
+                       MM_ATTRS_FLAG_RW,
+                       (void *) 0,
+                       MM_ATTRS_VALID_TYPE_INT_RANGE,
+                       0,
+                       4096
+               },
+               {
+                       (char *)"display_height",   /* dest height of fimcconvert ouput */
+                       MM_ATTRS_TYPE_INT,
+                       MM_ATTRS_FLAG_RW,
+                       (void *) 0,
+                       MM_ATTRS_VALID_TYPE_INT_RANGE,
+                       0,
+                       4096
+               },
+               {
+                       (char *)"display_evas_do_scaling",
+                       MM_ATTRS_TYPE_INT,
+                       MM_ATTRS_FLAG_RW,
+                       (void *) TRUE,
+                       MM_ATTRS_VALID_TYPE_INT_RANGE,
+                       FALSE,
+                       TRUE
+               },
+               {
+                       (char *)"display_x",
+                       MM_ATTRS_TYPE_INT,
+                       MM_ATTRS_FLAG_RW,
+                       (void *) 0,
+                       MM_ATTRS_VALID_TYPE_INT_RANGE,
+                       0,
+                       4096
+               },
+               {
+                       (char *)"display_y",
+                       MM_ATTRS_TYPE_INT,
+                       MM_ATTRS_FLAG_RW,
+                       (void *) 0,
+                       MM_ATTRS_VALID_TYPE_INT_RANGE,
+                       0,
+                       4096
+               },
+               {
+                       (char *)"hdcp_version",
+                       MM_ATTRS_TYPE_INT,
+                       MM_ATTRS_FLAG_RW,
+                       (void *) 0,
+                       MM_ATTRS_VALID_TYPE_INT_RANGE,
+                       0,
+                       2
+               },
+               {
+                       (char *)"hdcp_port",
+                       MM_ATTRS_TYPE_INT,
+                       MM_ATTRS_FLAG_RW,
+                       (void *) 0,
+                       MM_ATTRS_VALID_TYPE_INT_RANGE,
+                       0,
+                       2147483647
+               },
+       };
+
+       num_of_attrs = ARRAY_SIZE(wfd_attrs);
+
+       base = (mmf_attrs_construct_info_t *)malloc(num_of_attrs * sizeof(mmf_attrs_construct_info_t));
+
+       if (!base) {
+               debug_error("Cannot create mmwfd attribute\n");
+               goto ERROR;
+       }
+
+       /* initialize values of attributes */
+       for (idx = 0; idx < num_of_attrs; idx++) {
+               base[idx].name = wfd_attrs[idx].name;
+               base[idx].value_type = wfd_attrs[idx].value_type;
+               base[idx].flags = wfd_attrs[idx].flags;
+               base[idx].default_value = wfd_attrs[idx].default_value;
+       }
+
+       attrs = mmf_attrs_new_from_data(
+                                       "mmwfd_attrs",
+                                       base,
+                                       num_of_attrs,
+                                       NULL,
+                                       NULL);
+
+       if (base) {
+               g_free(base);
+               base = NULL;
+       }
+
+       if (!attrs) {
+               debug_error("Cannot create mmwfd attribute\n");
+               goto ERROR;
+       }
+
+       /* set validity type and range */
+       for (idx = 0; idx < num_of_attrs; idx++) {
+               switch (wfd_attrs[idx].valid_type) {
+                       case MM_ATTRS_VALID_TYPE_INT_RANGE: {
+                                       mmf_attrs_set_valid_type(attrs, idx, MM_ATTRS_VALID_TYPE_INT_RANGE);
+                                       mmf_attrs_set_valid_range(attrs, idx,
+                                                                               wfd_attrs[idx].value_min,
+                                                                               wfd_attrs[idx].value_max,
+                                                                               (int)wfd_attrs[idx].default_value);
+                               }
+                               break;
+
+                       case MM_ATTRS_VALID_TYPE_INT_ARRAY:
+                       case MM_ATTRS_VALID_TYPE_DOUBLE_ARRAY:
+                       case MM_ATTRS_VALID_TYPE_DOUBLE_RANGE:
+                       default:
+                               break;
+               }
+       }
+
+       debug_fleave();
+
+       return attrs;
+
+ERROR:
+       _mmwfd_deconstruct_attribute(attrs);
+
+       return (MMHandleType)NULL;
+}
+
+void
+_mmwfd_deconstruct_attribute(MMHandleType handle)
+{
+       debug_fenter();
+
+       return_if_fail(handle);
+
+       if (handle)
+               mmf_attrs_free(handle);
+
+       debug_fleave();
+}
+
+int
+_mmwfd_get_attribute(MMHandleType handle,  char **err_attr_name, const char *attribute_name, va_list args_list)
+{
+       int result = MM_ERROR_NONE;
+       MMHandleType attrs = 0;
+
+       debug_fenter();
+
+       /* NOTE : Don't need to check err_attr_name because it can be set NULL */
+       /* if it's not want to know it. */
+       return_val_if_fail(attribute_name, MM_ERROR_COMMON_INVALID_ARGUMENT);
+       return_val_if_fail(handle, MM_ERROR_COMMON_INVALID_ARGUMENT);
+
+       attrs = handle;
+
+       return_val_if_fail(attrs, MM_ERROR_COMMON_INVALID_ARGUMENT);
+
+       result = mm_attrs_get_valist(attrs, err_attr_name, attribute_name, args_list);
+
+       if (result != MM_ERROR_NONE)
+               debug_error("failed to get %s attribute\n", attribute_name);
+
+       debug_fleave();
+
+       return result;
+}
+
+int
+_mmwfd_set_attribute(MMHandleType handle,  char **err_attr_name, const char *attribute_name, va_list args_list)
+{
+       int result = MM_ERROR_NONE;
+       MMHandleType attrs = 0;
+
+       debug_fenter();
+
+       /* NOTE : Don't need to check err_attr_name because it can be set NULL */
+       /* if it's not want to know it. */
+       return_val_if_fail(attribute_name, MM_ERROR_COMMON_INVALID_ARGUMENT);
+       return_val_if_fail(handle, MM_ERROR_COMMON_INVALID_ARGUMENT);
+
+       attrs = handle;
+
+       return_val_if_fail(attrs, MM_ERROR_COMMON_INVALID_ARGUMENT);
+
+       /* set attributes and commit them */
+       result = mm_attrs_set_valist(attrs, err_attr_name, attribute_name, args_list);
+
+       if (result != MM_ERROR_NONE) {
+               debug_error("failed to set %s attribute\n", attribute_name);
+               return result;
+       }
+
+       /*__mmwfd_apply_attribute(handle, attribute_name); */
+
+       debug_fleave();
+
+       return result;
+}
+
+/* Currently not used. */
+/*static gboolean
+__mmwfd_apply_attribute(MMHandleType handle, const char *attribute_name)
+{
+  MMHandleType attrs = 0;
+  mm_wfd_t* wfd = 0;
+
+  debug_fenter();
+
+  return_val_if_fail(handle, MM_ERROR_COMMON_INVALID_ARGUMENT);
+  return_val_if_fail(attribute_name, MM_ERROR_COMMON_INVALID_ARGUMENT);
+
+  attrs = handle;
+
+  return_val_if_fail(attrs, MM_ERROR_COMMON_INVALID_ARGUMENT);
+
+  wfd = (mm_wfd_t*)handle;
+
+  // TODO: This function is not useful at this moment
+
+  debug_fleave();
+
+  return TRUE;
+}*/
+
+int
+_mmwfd_get_attributes_info(MMHandleType handle,  const char *attribute_name, MMWfdAttrsInfo *dst_info)
+{
+       int result = MM_ERROR_NONE;
+       MMHandleType attrs = 0;
+       MMAttrsInfo src_info = {0, };
+
+       debug_fenter();
+
+       return_val_if_fail(attribute_name, MM_ERROR_COMMON_INVALID_ARGUMENT);
+       return_val_if_fail(dst_info, MM_ERROR_COMMON_INVALID_ARGUMENT);
+       return_val_if_fail(handle, MM_ERROR_COMMON_INVALID_ARGUMENT);
+
+       attrs = handle;
+
+       return_val_if_fail(attrs, MM_ERROR_COMMON_INVALID_ARGUMENT);
+
+       result = mm_attrs_get_info_by_name(attrs, attribute_name, &src_info);
+
+       if (result != MM_ERROR_NONE) {
+               debug_error("failed to get attribute info\n");
+               return result;
+       }
+
+       memset(dst_info, 0x00, sizeof(MMWfdAttrsInfo));
+
+       dst_info->type = src_info.type;
+       dst_info->flag = src_info.flag;
+       dst_info->validity_type = src_info.validity_type;
+
+       switch (src_info.validity_type) {
+               case MM_ATTRS_VALID_TYPE_INT_ARRAY:
+                       dst_info->int_array.array = src_info.int_array.array;
+                       dst_info->int_array.count = src_info.int_array.count;
+                       dst_info->int_array.d_val = src_info.int_array.dval;
+                       break;
+
+               case MM_ATTRS_VALID_TYPE_INT_RANGE:
+                       dst_info->int_range.min = src_info.int_range.min;
+                       dst_info->int_range.max = src_info.int_range.max;
+                       dst_info->int_range.d_val = src_info.int_range.dval;
+                       break;
+
+               case MM_ATTRS_VALID_TYPE_DOUBLE_ARRAY:
+                       dst_info->double_array.array = src_info.double_array.array;
+                       dst_info->double_array.count = src_info.double_array.count;
+                       dst_info->double_array.d_val = src_info.double_array.dval;
+                       break;
+
+               case MM_ATTRS_VALID_TYPE_DOUBLE_RANGE:
+                       dst_info->double_range.min = src_info.double_range.min;
+                       dst_info->double_range.max = src_info.double_range.max;
+                       dst_info->double_range.d_val = src_info.double_range.dval;
+                       break;
+
+               default:
+                       break;
+       }
+
+       debug_fleave();
+
+       return result;
+}
+
+
diff --git a/src/mm_wfd_sink_ini.c b/src/mm_wfd_sink_ini.c
new file mode 100755 (executable)
index 0000000..24b7de4
--- /dev/null
@@ -0,0 +1,374 @@
+/*
+ * libmm-wfd
+ *
+ * Copyright (c) 2011 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: JongHyuk Choi <jhchoi.choi@samsung.com>, ByungWook Jang <bw.jang@samsung.com>,
+ * Manoj Kumar K <manojkumar.k@samsung.com>, Hyunil Park <hyunil46.park@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <glib.h>
+#include <glib/gstdio.h>
+#include <stdlib.h>
+#include <iniparser.h>
+#include <mm_error.h>
+#include "mm_wfd_sink_ini.h"
+#include "mm_wfd_sink_dlog.h"
+
+static gboolean loaded = FALSE;
+
+/* global variables here */
+#ifdef MM_WFD_SINK_DEFAULT_INI
+static gboolean        __generate_sink_default_ini(void);
+#endif
+
+static void __mm_wfd_sink_ini_check_status(void);
+
+/* macro */
+#define MM_WFD_SINK_INI_GET_STRING(x_dict, x_item, x_ini, x_default) \
+       do { \
+               gchar *str = NULL; \
+               gint length = 0; \
+               \
+               str = iniparser_getstring(x_dict, x_ini, (char *)x_default); \
+               if (str) { \
+                       length = strlen(str); \
+                       if ((length > 1) && (length < WFD_SINK_INI_MAX_STRLEN)) \
+                               strncpy(x_item, str, WFD_SINK_INI_MAX_STRLEN-1); \
+                       else \
+                               strncpy(x_item, x_default, WFD_SINK_INI_MAX_STRLEN-1); \
+               } else { \
+                       strncpy(x_item, x_default, WFD_SINK_INI_MAX_STRLEN-1); \
+               } \
+       } while (0);
+
+#ifdef MM_WFD_SINK_DEFAULT_INI
+static
+gboolean __generate_sink_default_ini(void)
+{
+       FILE *fp = NULL;
+       const gchar *default_ini = MM_WFD_SINK_DEFAULT_INI;
+
+
+       /* create new file */
+       fp = fopen(MM_WFD_SINK_INI_DEFAULT_PATH, "wt");
+
+       if (!fp) {
+               return FALSE;
+       }
+
+       /* writing default ini file */
+       if (strlen(default_ini) != fwrite(default_ini, 1, strlen(default_ini), fp)) {
+               fclose(fp);
+               return FALSE;
+       }
+
+       fclose(fp);
+       return TRUE;
+}
+#endif
+
+int
+mm_wfd_sink_ini_load(mm_wfd_sink_ini_t *ini)
+{
+       dictionary *dict = NULL;
+
+       wfd_sink_debug_fenter();
+
+
+       __mm_wfd_sink_ini_check_status();
+
+       /* first, try to load existing ini file */
+       dict = iniparser_load(MM_WFD_SINK_INI_DEFAULT_PATH);
+
+       /* if no file exists. create one with set of default values */
+       if (!dict) {
+#ifdef MM_WFD_SINK_DEFAULT_INI
+               wfd_sink_debug("No inifile found. create default ini file.\n");
+               if (FALSE == __generate_sink_default_ini()) {
+                       wfd_sink_error("Creating default ini file failed. Use default values.\n");
+               } else {
+                       /* load default ini */
+                       dict = iniparser_load(MM_WFD_SINK_INI_DEFAULT_PATH);
+               }
+#else
+               wfd_sink_error("No ini file found. \n");
+
+               return MM_ERROR_FILE_NOT_FOUND;
+#endif
+       }
+
+       /* get ini values */
+       memset(ini, 0, sizeof(mm_wfd_sink_ini_t));
+
+       if (dict) { /* if dict is available */
+               /* general */
+               MM_WFD_SINK_INI_GET_STRING(dict, ini->gst_param[0], "general:gstparam1", DEFAULT_GST_PARAM);
+               MM_WFD_SINK_INI_GET_STRING(dict, ini->gst_param[1], "general:gstparam2", DEFAULT_GST_PARAM);
+               MM_WFD_SINK_INI_GET_STRING(dict, ini->gst_param[2], "general:gstparam3", DEFAULT_GST_PARAM);
+               MM_WFD_SINK_INI_GET_STRING(dict, ini->gst_param[3], "general:gstparam4", DEFAULT_GST_PARAM);
+               MM_WFD_SINK_INI_GET_STRING(dict, ini->gst_param[4], "general:gstparam5", DEFAULT_GST_PARAM);
+               ini->generate_dot = iniparser_getboolean(dict, "general:generate dot", DEFAULT_GENERATE_DOT);
+               ini->enable_pad_probe = iniparser_getboolean(dict, "general:enable pad probe", DEFAULT_ENABLE_PAD_PROBE);
+               ini->state_change_timeout = iniparser_getint(dict, "general:state change timeout", DEFAULT_STATE_CHANGE_TIMEOUT);
+               ini->set_debug_property = iniparser_getboolean(dict, "general:set debug property", DEFAULT_SET_DEBUG_PROPERTY);
+               ini->enable_asm = iniparser_getboolean(dict, "general:enable asm", DEFAULT_ENABLE_ASM);
+               ini->jitter_buffer_latency = iniparser_getint(dict, "general:jitter buffer latency", DEFAULT_JITTER_BUFFER_LATENCY);
+               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_wfdsrc_pad_probe = iniparser_getboolean(dict, "general:enable wfdsrc pad probe", DEFAULT_ENABLE_WFDRTSPSRC_PAD_PROBE);
+
+
+               /* pipeline */
+               MM_WFD_SINK_INI_GET_STRING(dict, ini->name_of_source, "pipeline:wfdsrc element", DEFAULT_NAME_OF_SOURCE);
+               MM_WFD_SINK_INI_GET_STRING(dict, ini->name_of_tsdemux, "pipeline:tsdemux element", DEFAULT_NAME_OF_TSDEMUX);
+               MM_WFD_SINK_INI_GET_STRING(dict, ini->name_of_audio_hdcp, "pipeline:audio hdcp element", DEFAULT_NAME_OF_AUDIO_HDCP);
+               MM_WFD_SINK_INI_GET_STRING(dict, ini->name_of_aac_parser, "pipeline:aac parser element", DEFAULT_NAME_OF_AAC_PARSER);
+               MM_WFD_SINK_INI_GET_STRING(dict, ini->name_of_aac_decoder, "pipeline:aac decoder element", DEFAULT_NAME_OF_AAC_DECODER);
+               MM_WFD_SINK_INI_GET_STRING(dict, ini->name_of_ac3_parser, "pipeline:ac3 parser element", DEFAULT_NAME_OF_AC3_PARSER);
+               MM_WFD_SINK_INI_GET_STRING(dict, ini->name_of_ac3_decoder, "pipeline:ac3 decoder element", DEFAULT_NAME_OF_AC3_DECODER);
+               MM_WFD_SINK_INI_GET_STRING(dict, ini->name_of_lpcm_converter, "pipeline:lpcm converter element", DEFAULT_NAME_OF_LPCM_CONVERTER);
+               MM_WFD_SINK_INI_GET_STRING(dict, ini->name_of_lpcm_filter, "pipeline:lpcm filter element", DEFAULT_NAME_OF_LPCM_FILTER);
+               MM_WFD_SINK_INI_GET_STRING(dict, ini->name_of_audio_resampler, "pipeline:audio resampler element", DEFAULT_NAME_OF_AUDIO_RESAMPLER);
+               MM_WFD_SINK_INI_GET_STRING(dict, ini->name_of_audio_volume, "pipeline:audio volume element", DEFAULT_NAME_OF_AUDIO_VOLUME);
+               MM_WFD_SINK_INI_GET_STRING(dict, ini->name_of_audio_sink, "pipeline:audio sink element", DEFAULT_NAME_OF_AUDIO_SINK);
+               MM_WFD_SINK_INI_GET_STRING(dict, ini->name_of_video_hdcp, "pipeline:video hdcp element", DEFAULT_NAME_OF_VIDEO_HDCP);
+               MM_WFD_SINK_INI_GET_STRING(dict, ini->name_of_video_parser, "pipeline:video parser element", DEFAULT_NAME_OF_VIDEO_PARSER);
+               MM_WFD_SINK_INI_GET_STRING(dict, ini->name_of_video_capssetter, "pipeline:video capssetter element", DEFAULT_NAME_OF_VIDEO_CAPSSETTER);
+               MM_WFD_SINK_INI_GET_STRING(dict, ini->name_of_video_decoder, "pipeline:video decoder element", DEFAULT_NAME_OF_VIDEO_DECODER);
+               MM_WFD_SINK_INI_GET_STRING(dict, ini->name_of_video_converter, "pipeline:video converter element", DEFAULT_NAME_OF_VIDEO_CONVERTER);
+               MM_WFD_SINK_INI_GET_STRING(dict, ini->name_of_video_filter, "pipeline:video filter element", DEFAULT_NAME_OF_VIDEO_FILTER);
+               MM_WFD_SINK_INI_GET_STRING(dict, ini->name_of_video_sink, "pipeline:video sink element", DEFAULT_NAME_OF_VIDEO_SINK);
+               MM_WFD_SINK_INI_GET_STRING(dict, ini->name_of_video_evas_sink, "pipeline:video evas sink element", DEFAULT_NAME_OF_EVAS_VIDEO_SINK);
+
+               /* audio parameter*/
+               ini->audio_codec = iniparser_getint(dict, "audio param:audio codec", DEFAULT_AUDIO_CODEC);
+               ini->audio_latency = iniparser_getint(dict, "audio param:audio latency", DEFAULT_AUDIO_LATENCY);
+               ini->audio_channel = iniparser_getint(dict, "audio param:audio channels", DEFAULT_AUDIO_CHANNELS);
+               ini->audio_sampling_frequency = iniparser_getint(dict, "audio param:audio sampling frequency", DEFAULT_AUDIO_SAMP_FREQUENCY);
+
+               /* video parameter*/
+               ini->video_codec = iniparser_getint(dict, "video param:video codec", DEFAULT_VIDEO_CODEC);
+               ini->video_native_resolution = iniparser_getint(dict, "video param:video native resolution", DEFAULT_VIDEO_NATIVE_RESOLUTION);
+               ini->video_cea_support = iniparser_getint(dict, "video param:video cea support", DEFAULT_VIDEO_CEA_SUPPORT);
+               ini->video_vesa_support = iniparser_getint(dict, "video param:video vesa support", DEFAULT_VIDEO_VESA_SUPPORT);
+               ini->video_hh_support = iniparser_getint(dict, "video param:video hh support", DEFAULT_VIDEO_HH_SUPPORT);
+               ini->video_profile = iniparser_getint(dict, "video param:video profile", DEFAULT_VIDEO_PROFILE);
+               ini->video_level = iniparser_getint(dict, "video param:video level", DEFAULT_VIDEO_LEVEL);
+               ini->video_latency = iniparser_getint(dict, "video param:video latency", DEFAULT_VIDEO_LATENCY);
+               ini->video_vertical_resolution = iniparser_getint(dict, "video param:video vertical resolution", DEFAULT_VIDEO_VERTICAL_RESOLUTION);
+               ini->video_horizontal_resolution = iniparser_getint(dict, "video param:video horizontal resolution", DEFAULT_VIDEO_HORIZONTAL_RESOLUTION);
+               ini->video_minimum_slicing = iniparser_getint(dict, "video param:video minimum slicesize", DEFAULT_VIDEO_MIN_SLICESIZE);
+               ini->video_slice_enc_param = iniparser_getint(dict, "video param:video slice encoding params", DEFAULT_VIDEO_SLICE_ENC_PARAM);
+               ini->video_framerate_control_support = iniparser_getint(dict, "video param:video framerate control support", DEFAULT_VIDEO_FRAMERATE_CONTROL);
+
+               /* hdcp parameter*/
+               ini->hdcp_content_protection = iniparser_getint(dict, "hdcp param:hdcp content protection", DEFAULT_HDCP_CONTENT_PROTECTION);
+               ini->hdcp_port_no = iniparser_getint(dict, "hdcp param:hdcp port no", DEFAULT_HDCP_PORT_NO);
+       } else { /* if dict is not available just fill the structure with default value */
+               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);
+               strncpy(ini->gst_param[1], DEFAULT_GST_PARAM, WFD_SINK_INI_MAX_STRLEN - 1);
+               strncpy(ini->gst_param[2], DEFAULT_GST_PARAM, WFD_SINK_INI_MAX_STRLEN - 1);
+               strncpy(ini->gst_param[3], DEFAULT_GST_PARAM, WFD_SINK_INI_MAX_STRLEN - 1);
+               strncpy(ini->gst_param[4], DEFAULT_GST_PARAM, WFD_SINK_INI_MAX_STRLEN - 1);
+               ini->generate_dot =  DEFAULT_GENERATE_DOT;
+               ini->enable_pad_probe = DEFAULT_ENABLE_PAD_PROBE;
+               ini->state_change_timeout = DEFAULT_STATE_CHANGE_TIMEOUT;
+               ini->set_debug_property =  DEFAULT_SET_DEBUG_PROPERTY;
+               ini->enable_asm =  DEFAULT_ENABLE_ASM;
+               ini->jitter_buffer_latency = DEFAULT_JITTER_BUFFER_LATENCY;
+               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_wfdsrc_pad_probe = DEFAULT_ENABLE_WFDRTSPSRC_PAD_PROBE;
+
+               /* pipeline */
+               strncpy(ini->name_of_source, DEFAULT_NAME_OF_TSDEMUX, WFD_SINK_INI_MAX_STRLEN - 1);
+               strncpy(ini->name_of_tsdemux, DEFAULT_NAME_OF_TSDEMUX, WFD_SINK_INI_MAX_STRLEN - 1);
+               strncpy(ini->name_of_audio_hdcp, DEFAULT_NAME_OF_AUDIO_HDCP, WFD_SINK_INI_MAX_STRLEN - 1);
+               strncpy(ini->name_of_aac_parser, DEFAULT_NAME_OF_AAC_PARSER, WFD_SINK_INI_MAX_STRLEN - 1);
+               strncpy(ini->name_of_aac_decoder, DEFAULT_NAME_OF_AAC_DECODER, WFD_SINK_INI_MAX_STRLEN - 1);
+               strncpy(ini->name_of_ac3_parser, DEFAULT_NAME_OF_AC3_PARSER, WFD_SINK_INI_MAX_STRLEN - 1);
+               strncpy(ini->name_of_ac3_decoder, DEFAULT_NAME_OF_AC3_DECODER, WFD_SINK_INI_MAX_STRLEN - 1);
+               strncpy(ini->name_of_lpcm_converter, DEFAULT_NAME_OF_LPCM_CONVERTER, WFD_SINK_INI_MAX_STRLEN - 1);
+               strncpy(ini->name_of_lpcm_filter, DEFAULT_NAME_OF_LPCM_FILTER, WFD_SINK_INI_MAX_STRLEN - 1);
+               strncpy(ini->name_of_audio_resampler, DEFAULT_NAME_OF_AUDIO_RESAMPLER, WFD_SINK_INI_MAX_STRLEN - 1);
+               strncpy(ini->name_of_audio_volume, DEFAULT_NAME_OF_AUDIO_VOLUME, WFD_SINK_INI_MAX_STRLEN - 1);
+               strncpy(ini->name_of_audio_sink, DEFAULT_NAME_OF_AUDIO_SINK, WFD_SINK_INI_MAX_STRLEN - 1);
+               strncpy(ini->name_of_video_hdcp, DEFAULT_NAME_OF_VIDEO_HDCP, WFD_SINK_INI_MAX_STRLEN - 1);
+               strncpy(ini->name_of_video_parser, DEFAULT_NAME_OF_VIDEO_PARSER, WFD_SINK_INI_MAX_STRLEN - 1);
+               strncpy(ini->name_of_video_capssetter, DEFAULT_NAME_OF_VIDEO_CAPSSETTER, WFD_SINK_INI_MAX_STRLEN - 1);
+               strncpy(ini->name_of_video_decoder, DEFAULT_NAME_OF_VIDEO_DECODER, WFD_SINK_INI_MAX_STRLEN - 1);
+               strncpy(ini->name_of_video_converter, DEFAULT_NAME_OF_VIDEO_CONVERTER, WFD_SINK_INI_MAX_STRLEN - 1);
+               strncpy(ini->name_of_video_filter, DEFAULT_NAME_OF_VIDEO_FILTER, WFD_SINK_INI_MAX_STRLEN - 1);
+               strncpy(ini->name_of_video_sink, DEFAULT_NAME_OF_VIDEO_SINK, WFD_SINK_INI_MAX_STRLEN - 1);
+               strncpy(ini->name_of_video_evas_sink, DEFAULT_NAME_OF_EVAS_VIDEO_SINK, WFD_SINK_INI_MAX_STRLEN - 1);
+
+               /* audio parameter*/
+               ini->audio_codec = DEFAULT_AUDIO_CODEC;
+               ini->audio_latency = DEFAULT_AUDIO_LATENCY;
+               ini->audio_channel = DEFAULT_AUDIO_CHANNELS;
+               ini->audio_sampling_frequency = DEFAULT_AUDIO_SAMP_FREQUENCY;
+
+               /* video parameter*/
+               ini->video_codec = DEFAULT_VIDEO_CODEC;
+               ini->video_native_resolution = DEFAULT_VIDEO_NATIVE_RESOLUTION;
+               ini->video_cea_support = DEFAULT_VIDEO_CEA_SUPPORT;
+               ini->video_vesa_support = DEFAULT_VIDEO_VESA_SUPPORT;
+               ini->video_hh_support = DEFAULT_VIDEO_HH_SUPPORT;
+               ini->video_profile = DEFAULT_VIDEO_PROFILE;
+               ini->video_level = DEFAULT_VIDEO_LEVEL;
+               ini->video_latency = DEFAULT_VIDEO_LATENCY;
+               ini->video_vertical_resolution = DEFAULT_VIDEO_VERTICAL_RESOLUTION;
+               ini->video_horizontal_resolution = DEFAULT_VIDEO_HORIZONTAL_RESOLUTION;
+               ini->video_minimum_slicing = DEFAULT_VIDEO_MIN_SLICESIZE;
+               ini->video_slice_enc_param = DEFAULT_VIDEO_SLICE_ENC_PARAM;
+               ini->video_framerate_control_support = DEFAULT_VIDEO_FRAMERATE_CONTROL;
+
+               /* hdcp parameter*/
+               ini->hdcp_content_protection = DEFAULT_HDCP_CONTENT_PROTECTION;
+               ini->hdcp_port_no = DEFAULT_HDCP_PORT_NO;
+       }
+
+       /* free dict as we got our own structure */
+       iniparser_freedict(dict);
+
+
+       /* dump structure */
+       wfd_sink_debug("W-Fi Display Sink Initial Settings-----------------------------------\n");
+
+       /* general */
+       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) {
+               wfd_sink_debug("generate_dot is TRUE, dot file will be stored into /tmp/\n");
+               g_setenv("GST_DEBUG_DUMP_DOT_DIR", "/tmp/", FALSE);
+       }
+       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_wfdsrc_pad_probe : %d\n", ini->enable_wfdsrc_pad_probe);
+
+       /* pipeline */
+       wfd_sink_debug("name_of_source : %s\n", ini->name_of_source);
+       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);
+       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_capssetter : %s\n", ini->name_of_video_capssetter);
+       wfd_sink_debug("name_of_video_decoder : %s\n", ini->name_of_video_decoder);
+       wfd_sink_debug("name_of_video_converter : %s\n", ini->name_of_video_converter);
+       wfd_sink_debug("name_of_video_filter : %s\n", ini->name_of_video_filter);
+       wfd_sink_debug("name_of_video_sink : %s\n", ini->name_of_video_sink);
+       wfd_sink_debug("name_of_video_evas_sink : %s\n", ini->name_of_video_evas_sink);
+
+       /* audio parameter*/
+       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*/
+       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*/
+       wfd_sink_debug("hdcp_content_protection : %x\n", ini->hdcp_content_protection);
+       wfd_sink_debug("hdcp_port_no : %d\n", ini->hdcp_port_no);
+
+       wfd_sink_debug("---------------------------------------------------\n");
+
+       loaded = TRUE;
+
+       wfd_sink_debug_fleave();
+
+       return MM_ERROR_NONE;
+}
+
+
+static
+void __mm_wfd_sink_ini_check_status(void)
+{
+       struct stat ini_buff;
+
+       wfd_sink_debug_fenter();
+
+       if (g_stat(MM_WFD_SINK_INI_DEFAULT_PATH, &ini_buff) < 0) {
+               wfd_sink_error("failed to get mmfw_wfd_sink ini status\n");
+       } else {
+               if (ini_buff.st_size < 5) {
+                       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);
+               }
+       }
+
+       wfd_sink_debug_fleave();
+}
+
+int
+mm_wfd_sink_ini_unload(mm_wfd_sink_ini_t *ini)
+{
+       wfd_sink_debug_fenter();
+
+       loaded = FALSE;
+
+       wfd_sink_debug_fleave();
+
+       return MM_ERROR_NONE;
+}
diff --git a/src/mm_wfd_sink_manager.c b/src/mm_wfd_sink_manager.c
new file mode 100755 (executable)
index 0000000..3eb86f9
--- /dev/null
@@ -0,0 +1,169 @@
+/*
+ * libmm-wfd
+ *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: JongHyuk Choi <jhchoi.choi@samsung.com>, YeJin Cho <cho.yejin@samsung.com>,
+ * Seungbae Shin <seungbae.shin@samsung.com>, YoungHwan An <younghwan_.an@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+
+#include "mm_wfd_sink_manager.h"
+
+
+static gpointer __mm_wfd_sink_manager_thread(gpointer data);
+
+int _mm_wfd_sink_init_manager(mm_wfd_sink_t *wfd_sink)
+{
+       wfd_sink_debug_fenter();
+
+       wfd_sink_return_val_if_fail(wfd_sink, MM_ERROR_WFD_NOT_INITIALIZED);
+
+       /* create manager mutex */
+       g_mutex_init(&(wfd_sink->manager_thread_mutex));
+
+       /* create capture cond */
+       g_cond_init(&(wfd_sink->manager_thread_cond));
+
+       wfd_sink->manager_thread_cmd = NULL;
+       wfd_sink->manager_thread_exit = FALSE;
+
+       /* create manager thread */
+       wfd_sink->manager_thread =
+           g_thread_new("__mm_wfd_sink_manager_thread", __mm_wfd_sink_manager_thread, (gpointer)wfd_sink);
+       if (wfd_sink->manager_thread == NULL) {
+               wfd_sink_error("failed to create manager thread\n");
+               goto failed_to_init;
+       }
+
+       wfd_sink_debug_fleave();
+
+       return MM_ERROR_NONE;
+
+failed_to_init:
+       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)
+{
+       wfd_sink_debug_fenter();
+
+       wfd_sink_return_val_if_fail(wfd_sink, MM_ERROR_WFD_NOT_INITIALIZED);
+
+       /* release manager thread */
+       if (wfd_sink->manager_thread) {
+               WFD_SINK_MANAGER_APPEND_CMD(wfd_sink, WFD_SINK_MANAGER_CMD_EXIT);
+               WFD_SINK_MANAGER_SIGNAL_CMD(wfd_sink);
+
+               wfd_sink_debug("waitting for manager thread exit");
+               g_thread_join(wfd_sink->manager_thread);
+               g_mutex_clear(&(wfd_sink->manager_thread_mutex));
+               g_cond_clear(&(wfd_sink->manager_thread_cond));
+               wfd_sink_debug("manager thread released");
+       }
+
+       wfd_sink_debug_fleave();
+
+       return MM_ERROR_NONE;
+}
+
+static gpointer
+__mm_wfd_sink_manager_thread(gpointer data)
+{
+       mm_wfd_sink_t *wfd_sink = (mm_wfd_sink_t *) data;
+       WFDSinkManagerCMDType cmd = WFD_SINK_MANAGER_CMD_NONE;
+       GList *walk = NULL;
+
+       wfd_sink_debug_fenter();
+
+       wfd_sink_return_val_if_fail(wfd_sink, NULL);
+
+       if (wfd_sink->manager_thread_exit) {
+               wfd_sink_debug("exit manager thread...");
+               return NULL;
+       }
+
+       wfd_sink_debug("manager thread started. waiting for signal");
+
+       while (TRUE) {
+               WFD_SINK_MANAGER_LOCK(wfd_sink);
+               WFD_SINK_MANAGER_WAIT_CMD(wfd_sink);
+
+               for (walk = wfd_sink->manager_thread_cmd; walk; walk = g_list_next(walk)) {
+                       cmd = GPOINTER_TO_INT(walk->data);
+
+                       wfd_sink_debug("got command %d", cmd);
+
+                       switch (cmd) {
+                               case WFD_SINK_MANAGER_CMD_LINK_A_DECODEBIN:
+                                       wfd_sink_debug("try to link audio decodebin.");
+                                       if (MM_ERROR_NONE != __mm_wfd_sink_link_audio_decodebin(wfd_sink)) {
+                                               wfd_sink_error("failed to link audio decodebin.....\n");
+                                               goto EXIT;
+                                       }
+                                       break;
+                               case WFD_SINK_MANAGER_CMD_LINK_V_DECODEBIN:
+                                       wfd_sink_debug("try to link video decodebin.");
+                                       if (MM_ERROR_NONE != __mm_wfd_sink_link_video_decodebin(wfd_sink)) {
+                                               wfd_sink_error("failed to link video decodebin.....\n");
+                                               goto EXIT;
+                                       }
+                                       break;
+                               case WFD_SINK_MANAGER_CMD_PREPARE_A_PIPELINE:
+                                       wfd_sink_debug("try to prepare audio pipeline.");
+                                       if (MM_ERROR_NONE != __mm_wfd_sink_prepare_audio_pipeline(wfd_sink)) {
+                                               wfd_sink_error("failed to prepare audio pipeline.....\n");
+                                               goto EXIT;
+                                       }
+                                       break;
+                               case WFD_SINK_MANAGER_CMD_PREPARE_V_PIPELINE:
+                                       wfd_sink_debug("try to prepare video pipeline.");
+                                       if (MM_ERROR_NONE != __mm_wfd_sink_prepare_video_pipeline(wfd_sink)) {
+                                               wfd_sink_error("failed to prepare video pipeline.....\n");
+                                               goto EXIT;
+                                       }
+                                       break;
+                               case WFD_SINK_MANAGER_CMD_EXIT:
+                                       wfd_sink_debug("exiting manager thread");
+                                       goto EXIT;
+                                       break;
+                               default:
+                                       break;
+                       }
+               }
+
+               g_list_free(wfd_sink->manager_thread_cmd);
+               wfd_sink->manager_thread_cmd = NULL;
+
+               WFD_SINK_MANAGER_UNLOCK(wfd_sink);
+       }
+
+       wfd_sink_debug_fleave();
+
+       return NULL;
+
+EXIT:
+       wfd_sink->manager_thread_exit = TRUE;
+       g_list_free(wfd_sink->manager_thread_cmd);
+       wfd_sink->manager_thread_cmd = NULL;
+       WFD_SINK_MANAGER_UNLOCK(wfd_sink);
+
+       return NULL;
+}
+
diff --git a/src/mm_wfd_sink_priv.c b/src/mm_wfd_sink_priv.c
new file mode 100755 (executable)
index 0000000..dc17608
--- /dev/null
@@ -0,0 +1,3689 @@
+/*
+ * libmm-wfd
+ *
+ * Copyright (c) 2011 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: JongHyuk Choi <jhchoi.choi@samsung.com>, ByungWook Jang <bw.jang@samsung.com>,
+ * Maksym Ukhanov <m.ukhanov@samsung.com>, Hyunjun Ko <zzoon.ko@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <gst/gst.h>
+#include <gst/video/videooverlay.h>
+#include <Elementary.h>
+#include <Ecore_Wayland.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"
+#include "mm_wfd_sink_enum.h"
+#include "mm_wfd_sink_wayland.h"
+
+/* gstreamer */
+static int __mm_wfd_sink_init_gstreamer(mm_wfd_sink_t *wfd_sink);
+static int __mm_wfd_sink_create_pipeline(mm_wfd_sink_t *wfd_sink);
+static int __mm_wfd_sink_create_audio_decodebin(mm_wfd_sink_t *wfd_sink);
+static int __mm_wfd_sink_create_video_decodebin(mm_wfd_sink_t *wfd_sink);
+static int __mm_wfd_sink_destroy_audio_decodebin(mm_wfd_sink_t *wfd_sink);
+static int __mm_wfd_sink_destroy_video_decodebin(mm_wfd_sink_t *wfd_sink);
+static int __mm_wfd_sink_create_video_sinkbin(mm_wfd_sink_t *wfd_sink);
+static int __mm_wfd_sink_create_audio_sinkbin(mm_wfd_sink_t *wfd_sink);
+static int __mm_wfd_sink_destroy_pipeline(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);
+
+/* util */
+static void __mm_wfd_sink_dump_pipeline_state(mm_wfd_sink_t *wfd_sink);
+static void __mm_wfd_sink_prepare_video_resolution(gint resolution, guint *CEA_resolution, guint *VESA_resolution, guint *HH_resolution);
+
+int _mm_wfd_sink_create(mm_wfd_sink_t **wfd_sink)
+{
+       int result = MM_ERROR_NONE;
+
+       wfd_sink_debug_fenter();
+
+       wfd_sink_return_val_if_fail(wfd_sink, MM_ERROR_WFD_NOT_INITIALIZED);
+
+       mm_wfd_sink_t *new_wfd_sink = NULL;
+
+       /* create handle */
+       new_wfd_sink = g_malloc0(sizeof(mm_wfd_sink_t));
+       if (!new_wfd_sink) {
+               wfd_sink_error("failed to allocate memory for wi-fi display sink");
+               return MM_ERROR_WFD_NO_FREE_SPACE;
+       }
+
+       /* Initialize gstreamer related */
+       new_wfd_sink->attrs = 0;
+
+       new_wfd_sink->pipeline = NULL;
+       new_wfd_sink->audio_decodebin_is_linked = FALSE;
+       new_wfd_sink->video_decodebin_is_linked = FALSE;
+
+       /* Initialize timestamp compensation related */
+       new_wfd_sink->need_to_reset_basetime = FALSE;
+       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;
+       MMWFDSINK_PENDING_STATE(new_wfd_sink) =  MM_WFD_SINK_STATE_NONE;
+
+       /* initialize audio/video information */
+       new_wfd_sink->stream_info.audio_stream_info.codec = MM_WFD_SINK_AUDIO_CODEC_NONE;
+       new_wfd_sink->stream_info.audio_stream_info.channels = 0;
+       new_wfd_sink->stream_info.audio_stream_info.sample_rate = 0;
+       new_wfd_sink->stream_info.audio_stream_info.bitwidth = 0;
+       new_wfd_sink->stream_info.video_stream_info.codec = MM_WFD_SINK_VIDEO_CODEC_NONE;
+       new_wfd_sink->stream_info.video_stream_info.width = 0;
+       new_wfd_sink->stream_info.video_stream_info.height = 0;
+       new_wfd_sink->stream_info.video_stream_info.frame_rate = 0;
+
+       /* Initialize command */
+       new_wfd_sink->cmd = MM_WFD_SINK_COMMAND_CREATE;
+       new_wfd_sink->waiting_cmd = FALSE;
+
+       /* Initialize manager related */
+       new_wfd_sink->manager_thread = NULL;
+       new_wfd_sink->manager_thread_cmd = NULL;
+       new_wfd_sink->manager_thread_exit = FALSE;
+
+       /* Initialize video resolution */
+       new_wfd_sink->supportive_resolution = MM_WFD_SINK_RESOLUTION_UNKNOWN;
+
+       /* construct attributes */
+       new_wfd_sink->attrs = _mmwfd_construct_attribute((MMHandleType)new_wfd_sink);
+       if (!new_wfd_sink->attrs) {
+               MMWFDSINK_FREEIF(new_wfd_sink);
+               wfd_sink_error("failed to set attribute");
+               return MM_ERROR_WFD_INTERNAL;
+       }
+
+       /* load ini for initialize */
+       result = mm_wfd_sink_ini_load(&new_wfd_sink->ini);
+       if (result != MM_ERROR_NONE) {
+               wfd_sink_error("failed to load ini file");
+               goto fail_to_load_ini;
+       }
+       new_wfd_sink->need_to_reset_basetime = new_wfd_sink->ini.enable_reset_basetime;
+
+       /* initialize manager */
+       result = _mm_wfd_sink_init_manager(new_wfd_sink);
+       if (result < MM_ERROR_NONE) {
+               wfd_sink_error("failed to init manager : %d", result);
+               goto fail_to_init;
+       }
+
+       /* initialize gstreamer */
+       result = __mm_wfd_sink_init_gstreamer(new_wfd_sink);
+       if (result < MM_ERROR_NONE) {
+               wfd_sink_error("failed to init gstreamer : %d", result);
+               goto fail_to_init;
+       }
+
+       /* set state */
+       __mm_wfd_sink_set_state(new_wfd_sink,  MM_WFD_SINK_STATE_NULL);
+
+       /* now take handle */
+       *wfd_sink = new_wfd_sink;
+
+       wfd_sink_debug_fleave();
+
+       return result;
+
+       /* ERRORS */
+fail_to_init:
+       mm_wfd_sink_ini_unload(&new_wfd_sink->ini);
+fail_to_load_ini:
+       _mmwfd_deconstruct_attribute(new_wfd_sink->attrs);
+       MMWFDSINK_FREEIF(new_wfd_sink);
+
+       *wfd_sink = NULL;
+
+       return result;
+}
+
+int _mm_wfd_sink_prepare(mm_wfd_sink_t *wfd_sink)
+{
+       int result = MM_ERROR_NONE;
+
+       wfd_sink_debug_fenter();
+
+       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_PREPARE);
+
+       /* construct pipeline */
+       /* create main pipeline */
+       result = __mm_wfd_sink_create_pipeline(wfd_sink);
+       if (result < MM_ERROR_NONE) {
+               wfd_sink_error("failed to create pipeline : %d", result);
+               goto fail_to_create;
+       }
+
+       /* create video decodebin */
+       result = __mm_wfd_sink_create_video_decodebin(wfd_sink);
+       if (result < MM_ERROR_NONE) {
+               wfd_sink_error("failed to create video decodebin %d", result);
+               goto fail_to_create;
+       }
+
+       /* create video sinkbin */
+       result = __mm_wfd_sink_create_video_sinkbin(wfd_sink);
+       if (result < MM_ERROR_NONE) {
+               wfd_sink_error("failed to create video sinkbin %d", result);
+               goto fail_to_create;
+       }
+
+       /* create audio decodebin */
+       result = __mm_wfd_sink_create_audio_decodebin(wfd_sink);
+       if (result < MM_ERROR_NONE) {
+               wfd_sink_error("fail to create audio decodebin : %d", result);
+               goto fail_to_create;
+       }
+
+       /* create audio sinkbin */
+       result = __mm_wfd_sink_create_audio_sinkbin(wfd_sink);
+       if (result < MM_ERROR_NONE) {
+               wfd_sink_error("fail to create audio sinkbin : %d", result);
+               goto fail_to_create;
+       }
+
+       /* set pipeline READY state */
+       result = __mm_wfd_sink_set_pipeline_state(wfd_sink, GST_STATE_READY, TRUE);
+       if (result < MM_ERROR_NONE) {
+               wfd_sink_error("failed to set state : %d", result);
+               goto fail_to_create;
+       }
+
+       /* set state */
+       __mm_wfd_sink_set_state(wfd_sink,  MM_WFD_SINK_STATE_PREPARED);
+
+       wfd_sink_debug_fleave();
+
+       return result;
+
+       /* ERRORS */
+fail_to_create:
+       /* need to destroy pipeline already created */
+       __mm_wfd_sink_destroy_pipeline(wfd_sink);
+       return result;
+}
+
+int _mm_wfd_sink_connect(mm_wfd_sink_t *wfd_sink, const char *uri)
+{
+       int result = MM_ERROR_NONE;
+
+       wfd_sink_debug_fenter();
+
+       wfd_sink_return_val_if_fail(uri && strlen(uri) > strlen("rtsp://"), MM_ERROR_WFD_INVALID_ARGUMENT);
+       wfd_sink_return_val_if_fail(wfd_sink &&
+                                               wfd_sink->pipeline &&
+                                               wfd_sink->pipeline->mainbin &&
+                                               wfd_sink->pipeline->mainbin[WFD_SINK_M_PIPE].gst &&
+                                               wfd_sink->pipeline->mainbin[WFD_SINK_M_SRC].gst &&
+                                               wfd_sink->pipeline->mainbin[WFD_SINK_M_DEPAY].gst &&
+                                               wfd_sink->pipeline->mainbin[WFD_SINK_M_DEMUX].gst,
+                                               MM_ERROR_WFD_NOT_INITIALIZED);
+
+       /* check current wi-fi display sink state */
+       MMWFDSINK_CHECK_STATE(wfd_sink, MM_WFD_SINK_COMMAND_CONNECT);
+
+       wfd_sink_debug("try to connect to %s.....", GST_STR_NULL(uri));
+
+       /* set uri to wfdsrc */
+       g_object_set(G_OBJECT(wfd_sink->pipeline->mainbin[WFD_SINK_M_SRC].gst), "location", uri, NULL);
+
+       /* set pipeline PAUSED state */
+       result = __mm_wfd_sink_set_pipeline_state(wfd_sink, GST_STATE_PAUSED, TRUE);
+       if (result < MM_ERROR_NONE) {
+               wfd_sink_error("failed to set state : %d", result);
+               return result;
+       }
+
+       wfd_sink_debug_fleave();
+
+       return result;
+}
+
+int _mm_wfd_sink_start(mm_wfd_sink_t *wfd_sink)
+{
+       int result = MM_ERROR_NONE;
+
+       wfd_sink_debug_fenter();
+
+       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);
+
+       WFD_SINK_MANAGER_LOCK(wfd_sink) ;
+       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) {
+               wfd_sink_error("failed to set state : %d", result);
+               return result;
+       }
+
+       wfd_sink_debug_fleave();
+
+       return result;
+}
+
+int _mm_wfd_sink_pause(mm_wfd_sink_t *wfd_sink)
+{
+       int result = MM_ERROR_NONE;
+
+       wfd_sink_debug_fenter();
+
+       wfd_sink_return_val_if_fail(wfd_sink &&
+                                               wfd_sink->pipeline &&
+                                               wfd_sink->pipeline->mainbin &&
+                                               wfd_sink->pipeline->mainbin[WFD_SINK_M_PIPE].gst &&
+                                               wfd_sink->pipeline->mainbin[WFD_SINK_M_SRC].gst,
+                                               MM_ERROR_WFD_NOT_INITIALIZED);
+
+       /* check current wi-fi display sink state */
+       MMWFDSINK_CHECK_STATE(wfd_sink, MM_WFD_SINK_COMMAND_PAUSE);
+
+       g_signal_emit_by_name(wfd_sink->pipeline->mainbin[WFD_SINK_M_SRC].gst, "pause", NULL);
+
+       wfd_sink_debug_fleave();
+
+       return result;
+}
+
+int _mm_wfd_sink_resume(mm_wfd_sink_t *wfd_sink)
+{
+       int result = MM_ERROR_NONE;
+
+       wfd_sink_debug_fenter();
+
+       wfd_sink_return_val_if_fail(wfd_sink &&
+                                               wfd_sink->pipeline &&
+                                               wfd_sink->pipeline->mainbin &&
+                                               wfd_sink->pipeline->mainbin[WFD_SINK_M_PIPE].gst &&
+                                               wfd_sink->pipeline->mainbin[WFD_SINK_M_SRC].gst,
+                                               MM_ERROR_WFD_NOT_INITIALIZED);
+
+       /* check current wi-fi display sink state */
+       MMWFDSINK_CHECK_STATE(wfd_sink, MM_WFD_SINK_COMMAND_RESUME);
+
+       g_signal_emit_by_name(wfd_sink->pipeline->mainbin[WFD_SINK_M_SRC].gst, "resume", NULL);
+
+       wfd_sink_debug_fleave();
+
+       return result;
+}
+
+int _mm_wfd_sink_disconnect(mm_wfd_sink_t *wfd_sink)
+{
+       int result = MM_ERROR_NONE;
+
+       wfd_sink_debug_fenter();
+
+       wfd_sink_return_val_if_fail(wfd_sink &&
+                                               wfd_sink->pipeline &&
+                                               wfd_sink->pipeline->mainbin &&
+                                               wfd_sink->pipeline->mainbin[WFD_SINK_M_PIPE].gst &&
+                                               wfd_sink->pipeline->mainbin[WFD_SINK_M_SRC].gst,
+                                               MM_ERROR_WFD_NOT_INITIALIZED);
+
+       /* check current wi-fi display sink state */
+       MMWFDSINK_CHECK_STATE(wfd_sink, MM_WFD_SINK_COMMAND_DISCONNECT);
+
+       WFD_SINK_MANAGER_APPEND_CMD(wfd_sink, WFD_SINK_MANAGER_CMD_EXIT);
+       WFD_SINK_MANAGER_SIGNAL_CMD(wfd_sink);
+
+       g_signal_emit_by_name(wfd_sink->pipeline->mainbin[WFD_SINK_M_SRC].gst, "close", NULL);
+
+       wfd_sink_debug_fleave();
+
+       return result;
+}
+
+int _mm_wfd_sink_unprepare(mm_wfd_sink_t *wfd_sink)
+{
+       int result = MM_ERROR_NONE;
+
+       wfd_sink_debug_fenter();
+
+       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_UNPREPARE);
+
+       WFD_SINK_MANAGER_APPEND_CMD(wfd_sink, WFD_SINK_MANAGER_CMD_EXIT);
+       WFD_SINK_MANAGER_SIGNAL_CMD(wfd_sink);
+
+       /* release pipeline */
+       result =  __mm_wfd_sink_destroy_pipeline(wfd_sink);
+       if (result != MM_ERROR_NONE) {
+               wfd_sink_error("failed to destory pipeline");
+               return MM_ERROR_WFD_INTERNAL;
+       } else {
+               wfd_sink_debug("success to destory pipeline");
+       }
+
+       /* set state */
+       __mm_wfd_sink_set_state(wfd_sink,  MM_WFD_SINK_STATE_NULL);
+
+       wfd_sink_debug_fleave();
+
+       return result;
+}
+
+int _mm_wfd_sink_destroy(mm_wfd_sink_t *wfd_sink)
+{
+       int result = MM_ERROR_NONE;
+
+       wfd_sink_debug_fenter();
+
+       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);
+
+       /* unload ini */
+       mm_wfd_sink_ini_unload(&wfd_sink->ini);
+
+       /* release attributes */
+       _mmwfd_deconstruct_attribute(wfd_sink->attrs);
+
+       if (MM_ERROR_NONE != _mm_wfd_sink_release_manager(wfd_sink)) {
+               wfd_sink_error("failed to release manager");
+               return MM_ERROR_WFD_INTERNAL;
+       }
+
+
+       /* set state */
+       __mm_wfd_sink_set_state(wfd_sink,  MM_WFD_SINK_STATE_NONE);
+
+       wfd_sink_debug_fleave();
+
+       return result;
+}
+
+int _mm_wfd_set_message_callback(mm_wfd_sink_t *wfd_sink, MMWFDMessageCallback callback, void *user_data)
+{
+       int result = MM_ERROR_NONE;
+
+       wfd_sink_debug_fenter();
+
+       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;
+
+       wfd_sink_debug_fleave();
+
+       return result;
+}
+
+static int __mm_wfd_sink_init_gstreamer(mm_wfd_sink_t *wfd_sink)
+{
+       int result = MM_ERROR_NONE;
+       gint *argc = NULL;
+       gchar **argv = NULL;
+       static const int max_argc = 50;
+       GError *err = NULL;
+       gint i = 0;
+
+       wfd_sink_debug_fenter();
+
+       /* alloc */
+       argc = calloc(1, sizeof(gint));
+       argv = calloc(max_argc, sizeof(gchar *));
+       if (!argc || !argv) {
+               wfd_sink_error("failed to allocate memory for wfdsink");
+
+               MMWFDSINK_FREEIF(argv);
+               MMWFDSINK_FREEIF(argc);
+
+               return MM_ERROR_WFD_NO_FREE_SPACE;
+       }
+
+       /* we would not do fork for scanning plugins */
+       argv[*argc] = g_strdup("--gst-disable-registry-fork");
+       (*argc)++;
+
+       /* check disable registry scan */
+       argv[*argc] = g_strdup("--gst-disable-registry-update");
+       (*argc)++;
+
+       /* check disable segtrap */
+       argv[*argc] = g_strdup("--gst-disable-segtrap");
+       (*argc)++;
+
+       /* check ini */
+       for (i = 0; i < 5; i++) {
+               if (strlen(wfd_sink->ini.gst_param[i]) > 2) {
+                       wfd_sink_debug("set %s", wfd_sink->ini.gst_param[i]);
+                       argv[*argc] = g_strdup(wfd_sink->ini.gst_param[i]);
+                       (*argc)++;
+               }
+       }
+
+       wfd_sink_debug("initializing gstreamer with following parameter");
+       wfd_sink_debug("argc : %d", *argc);
+
+       for (i = 0; i < *argc; i++) {
+               wfd_sink_debug("argv[%d] : %s", i, argv[i]);
+       }
+
+       /* initializing gstreamer */
+       if (!gst_init_check(argc, &argv, &err)) {
+               wfd_sink_error("failed to initialize gstreamer: %s", err ? err->message : "unknown error occurred");
+               if (err)
+                       g_error_free(err);
+
+               result = MM_ERROR_WFD_INTERNAL;
+       }
+
+       /* release */
+       for (i = 0; i < *argc; i++) {
+               MMWFDSINK_FREEIF(argv[i]);
+       }
+       MMWFDSINK_FREEIF(argv);
+       MMWFDSINK_FREEIF(argc);
+
+       wfd_sink_debug_fleave();
+
+       return result;
+}
+
+static GstBusSyncReply
+_mm_wfd_bus_sync_callback(GstBus *bus, GstMessage *message, gpointer 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:
+                       break;
+               case GST_MESSAGE_DURATION:
+                       break;
+               case GST_MESSAGE_STATE_CHANGED: {
+                               /* 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 (!GST_IS_PIPELINE(GST_MESSAGE_SRC(message)))
+                                       ret = GST_BUS_DROP;
+                       }
+                       break;
+               default:
+                       break;
+       }
+
+       return ret;
+}
+
+static gboolean
+_mm_wfd_sink_msg_callback(GstBus *bus, GstMessage *msg, gpointer data)
+{
+       mm_wfd_sink_t *wfd_sink = (mm_wfd_sink_t *) data;
+       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);
+
+       wfd_sink_debug("got %s from %s",
+                                       GST_STR_NULL(GST_MESSAGE_TYPE_NAME(msg)),
+                                       GST_STR_NULL(GST_OBJECT_NAME(GST_MESSAGE_SRC(msg))));
+
+       switch (GST_MESSAGE_TYPE(msg)) {
+               case GST_MESSAGE_ERROR: {
+                               GError *error = NULL;
+                               gchar *debug = NULL;
+
+                               /* get error code */
+                               gst_message_parse_error(msg, &error, &debug);
+
+                               wfd_sink_error("error : %s", error->message);
+                               wfd_sink_error("debug : %s", debug);
+
+                               MMWFDSINK_FREEIF(debug);
+                               g_error_free(error);
+                       }
+                       break;
+
+               case GST_MESSAGE_WARNING: {
+                               char *debug = NULL;
+                               GError *error = NULL;
+
+                               gst_message_parse_warning(msg, &error, &debug);
+
+                               wfd_sink_warning("warning : %s", error->message);
+                               wfd_sink_warning("debug : %s", debug);
+
+                               MMWFDSINK_FREEIF(debug);
+                               g_error_free(error);
+                       }
+                       break;
+
+               case GST_MESSAGE_STATE_CHANGED: {
+                               const GValue *voldstate, *vnewstate, *vpending;
+                               GstState oldstate, newstate, pending;
+                               const GstStructure *structure;
+
+                               /* we only handle messages from pipeline */
+                               if (msg->src != (GstObject *)wfd_sink->pipeline->mainbin[WFD_SINK_M_PIPE].gst)
+                                       break;
+
+                               /* get state info from msg */
+                               structure = gst_message_get_structure(msg);
+                               if (structure == NULL)
+                                       break;
+
+                               voldstate = gst_structure_get_value(structure, "old-state");
+                               vnewstate = gst_structure_get_value(structure, "new-state");
+                               vpending = gst_structure_get_value(structure, "pending-state");
+                               if (voldstate == NULL || vnewstate == NULL || vpending == NULL)
+                                       break;
+
+                               oldstate = (GstState)voldstate->data[0].v_int;
+                               newstate = (GstState)vnewstate->data[0].v_int;
+                               pending = (GstState)vpending->data[0].v_int;
+
+                               wfd_sink_debug("state changed [%s] : %s--->%s final : %s",
+                                                       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) {
+                                       wfd_sink_debug("pipeline reports state transition to old state");
+                                       break;
+                               }
+
+                               switch (newstate) {
+                                       case GST_STATE_VOID_PENDING:
+                                       case GST_STATE_NULL:
+                                       case GST_STATE_READY:
+                                       case GST_STATE_PAUSED:
+                                       case GST_STATE_PLAYING:
+                                       default:
+                                               break;
+                               }
+                       }
+                       break;
+
+               case GST_MESSAGE_CLOCK_LOST: {
+                               GstClock *clock = NULL;
+                               gst_message_parse_clock_lost(msg, &clock);
+                               wfd_sink_debug("The current clock[%s] as selected by the pipeline became unusable.", (clock ? GST_OBJECT_NAME(clock) : "NULL"));
+                       }
+                       break;
+
+               case GST_MESSAGE_NEW_CLOCK: {
+                               GstClock *clock = NULL;
+                               gst_message_parse_new_clock(msg, &clock);
+                               if (!clock)
+                                       break;
+
+                               if (wfd_sink->clock) {
+                                       if (wfd_sink->clock != clock)
+                                               wfd_sink_debug("clock is changed! [%s] -->[%s]",
+                                                               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]",
+                                                               GST_STR_NULL(GST_OBJECT_NAME(clock)));
+                               } else {
+                                       wfd_sink_debug("new clock [%s] was selected in the pipeline",
+                                                               (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);
+                               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;
+
+                               structure_name = gst_structure_get_name(message_structure);
+                               if (structure_name) {
+                                       wfd_sink_debug("got element specific message[%s]", GST_STR_NULL(structure_name));
+                                       if (g_strrstr(structure_name, "GstUDPSrcTimeout")) {
+                                               wfd_sink_error("Got %s, post error message", GST_STR_NULL(structure_name));
+                                               MMWFDSINK_POST_MESSAGE(wfd_sink,
+                                                                                               MM_ERROR_WFD_INTERNAL,
+                                                                                               MMWFDSINK_CURRENT_STATE(wfd_sink));
+                                       } else if (g_strrstr(structure_name, "GstWFDSrcSessionTimeout")) {
+                                               wfd_sink_error("Got %s, post error message", GST_STR_NULL(structure_name));
+                                               MMWFDSINK_POST_MESSAGE(wfd_sink,
+                                                                                               MM_ERROR_WFD_INTERNAL,
+                                                                                               MMWFDSINK_CURRENT_STATE(wfd_sink));
+                                       }
+                               }
+                       }
+                       break;
+
+               case GST_MESSAGE_PROGRESS: {
+                               GstProgressType type = GST_PROGRESS_TYPE_ERROR;
+                               gchar *category = NULL, *text = NULL;
+
+                               gst_message_parse_progress(msg, &type, &category, &text);
+                               wfd_sink_debug("%s : %s ", GST_STR_NULL(category), GST_STR_NULL(text));
+
+                               switch (type) {
+                                       case GST_PROGRESS_TYPE_START:
+                                               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")) {
+                                                       __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")) {
+                                                       wfd_sink_error("got error : %s", 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")) {
+                                                       wfd_sink_error("got error : %s", 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", 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", 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 {
+                                                       wfd_sink_error("got error : %s", GST_STR_NULL(text));
+                                               }
+                                               break;
+                                       default:
+                                               wfd_sink_error("progress message has no type");
+                                               return ret;
+                               }
+
+                               MMWFDSINK_FREEIF(category);
+                               MMWFDSINK_FREEIF(text);
+                       }
+                       break;
+               case GST_MESSAGE_ASYNC_START:
+                       wfd_sink_debug("GST_MESSAGE_ASYNC_START : %s", gst_element_get_name(GST_MESSAGE_SRC(msg)));
+                       break;
+               case GST_MESSAGE_ASYNC_DONE:
+                       wfd_sink_debug("GST_MESSAGE_ASYNC_DONE : %s", 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:
+                       wfd_sink_debug("unhandled message");
+                       break;
+       }
+
+       return ret;
+}
+
+static int
+__mm_wfd_sink_gst_element_add_bucket_to_bin(GstBin *bin, GList *element_bucket, gboolean need_prepare)
+{
+       GList *bucket = element_bucket;
+       MMWFDSinkGstElement *element = NULL;
+       int successful_add_count = 0;
+
+       wfd_sink_debug_fenter();
+
+       wfd_sink_return_val_if_fail(element_bucket, 0);
+       wfd_sink_return_val_if_fail(bin, 0);
+
+       for (; bucket; bucket = bucket->next) {
+               element = (MMWFDSinkGstElement *)bucket->data;
+
+               if (element && element->gst) {
+                       if (need_prepare)
+                               gst_element_set_state(GST_ELEMENT(element->gst), GST_STATE_READY);
+
+                       if (!gst_bin_add(GST_BIN(bin), GST_ELEMENT(element->gst))) {
+                               wfd_sink_error("failed to add element [%s] to bin [%s]",
+                                               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]",
+                                               GST_STR_NULL(GST_ELEMENT_NAME(GST_ELEMENT(element->gst))),
+                                               GST_STR_NULL(GST_ELEMENT_NAME(GST_ELEMENT_CAST(bin))));
+
+                       successful_add_count++;
+               }
+       }
+
+       wfd_sink_debug_fleave();
+
+       return successful_add_count;
+}
+
+static int
+__mm_wfd_sink_gst_element_link_bucket(GList *element_bucket)
+{
+       GList *bucket = element_bucket;
+       MMWFDSinkGstElement *element = NULL;
+       MMWFDSinkGstElement *prv_element = NULL;
+       gint successful_link_count = 0;
+
+       wfd_sink_debug_fenter();
+
+       wfd_sink_return_val_if_fail(element_bucket, -1);
+
+       prv_element = (MMWFDSinkGstElement *)bucket->data;
+       bucket = bucket->next;
+
+       for (; bucket; bucket = bucket->next) {
+               element = (MMWFDSinkGstElement *)bucket->data;
+
+               if (element && element->gst) {
+                       if (gst_element_link(GST_ELEMENT(prv_element->gst), GST_ELEMENT(element->gst))) {
+                               wfd_sink_debug("linking [%s] to [%s] success",
+                                                       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 {
+                               wfd_sink_error("linking [%s] to [%s] failed",
+                                                       GST_STR_NULL(GST_ELEMENT_NAME(GST_ELEMENT(prv_element->gst))),
+                                                       GST_STR_NULL(GST_ELEMENT_NAME(GST_ELEMENT(element->gst))));
+                               return -1;
+                       }
+               }
+
+               prv_element = element;
+       }
+
+       wfd_sink_debug_fleave();
+
+       return successful_link_count;
+}
+
+static int
+__mm_wfd_sink_check_state(mm_wfd_sink_t *wfd_sink, MMWFDSinkCommandType cmd)
+{
+       MMWFDSinkStateType cur_state = MM_WFD_SINK_STATE_NONE;
+
+       wfd_sink_debug_fenter();
+
+       wfd_sink_return_val_if_fail(wfd_sink, MM_ERROR_WFD_NOT_INITIALIZED);
+
+       MMWFDSINK_PRINT_STATE(wfd_sink);
+
+       cur_state = MMWFDSINK_CURRENT_STATE(wfd_sink);
+
+       switch (cmd) {
+               case MM_WFD_SINK_COMMAND_CREATE: {
+                               if (cur_state != MM_WFD_SINK_STATE_NONE)
+                                       goto invalid_state;
+
+                               MMWFDSINK_PENDING_STATE(wfd_sink) = MM_WFD_SINK_STATE_NULL;
+                       }
+                       break;
+
+               case MM_WFD_SINK_COMMAND_PREPARE: {
+                               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_PREPARED;
+                       }
+                       break;
+
+               case MM_WFD_SINK_COMMAND_CONNECT: {
+                               if (cur_state == MM_WFD_SINK_STATE_CONNECTED)
+                                       goto no_operation;
+                               else if (cur_state != MM_WFD_SINK_STATE_PREPARED)
+                                       goto invalid_state;
+
+                               MMWFDSINK_PENDING_STATE(wfd_sink) = MM_WFD_SINK_STATE_CONNECTED;
+                       }
+                       break;
+
+               case MM_WFD_SINK_COMMAND_START: {
+                               if (cur_state == MM_WFD_SINK_STATE_PLAYING)
+                                       goto no_operation;
+                               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_PAUSE: {
+                               if (cur_state == MM_WFD_SINK_STATE_PAUSED)
+                                       goto no_operation;
+                               else if (cur_state != MM_WFD_SINK_STATE_PLAYING)
+                                       goto invalid_state;
+
+                               MMWFDSINK_PENDING_STATE(wfd_sink) = MM_WFD_SINK_STATE_PAUSED;
+                       }
+                       break;
+
+               case MM_WFD_SINK_COMMAND_RESUME: {
+                               if (cur_state == MM_WFD_SINK_STATE_PLAYING)
+                                       goto no_operation;
+                               else if (cur_state != MM_WFD_SINK_STATE_PAUSED)
+                                       goto invalid_state;
+
+                               MMWFDSINK_PENDING_STATE(wfd_sink) = MM_WFD_SINK_STATE_PLAYING;
+                       }
+                       break;
+
+               case MM_WFD_SINK_COMMAND_DISCONNECT: {
+                               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_DISCONNECTED;
+                       }
+                       break;
+
+               case MM_WFD_SINK_COMMAND_UNPREPARE: {
+                               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;
+                       }
+                       break;
+
+               case MM_WFD_SINK_COMMAND_DESTROY: {
+                               if (cur_state == MM_WFD_SINK_STATE_NONE)
+                                       goto no_operation;
+
+                               MMWFDSINK_PENDING_STATE(wfd_sink) = MM_WFD_SINK_STATE_NONE;
+                       }
+                       break;
+
+               default:
+                       break;
+       }
+
+       wfd_sink->cmd = cmd;
+
+       wfd_sink_debug_fleave();
+
+       return MM_ERROR_NONE;
+
+no_operation:
+       wfd_sink_debug("already %s state, nothing to do.", MMWFDSINK_STATE_GET_NAME(cur_state));
+       return MM_ERROR_WFD_NO_OP;
+
+       /* ERRORS */
+invalid_state:
+       wfd_sink_error("current state is invalid.", 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)
+{
+       wfd_sink_debug_fenter();
+
+       wfd_sink_return_val_if_fail(wfd_sink, MM_ERROR_WFD_NOT_INITIALIZED);
+
+       if (MMWFDSINK_CURRENT_STATE(wfd_sink) == state) {
+               wfd_sink_error("already state(%s)", MMWFDSINK_STATE_GET_NAME(state));
+               MMWFDSINK_PENDING_STATE(wfd_sink) = MM_WFD_SINK_STATE_NONE;
+               return MM_ERROR_NONE;
+       }
+
+       /* update wi-fi display state */
+       MMWFDSINK_PREVIOUS_STATE(wfd_sink) = MMWFDSINK_CURRENT_STATE(wfd_sink);
+       MMWFDSINK_CURRENT_STATE(wfd_sink) = state;
+
+       if (MMWFDSINK_CURRENT_STATE(wfd_sink) == MMWFDSINK_PENDING_STATE(wfd_sink))
+               MMWFDSINK_PENDING_STATE(wfd_sink) = MM_WFD_SINK_STATE_NONE;
+
+       /* poset state message to application */
+       MMWFDSINK_POST_MESSAGE(wfd_sink,
+                                               MM_ERROR_NONE,
+                                               MMWFDSINK_CURRENT_STATE(wfd_sink));
+
+       /* print state */
+       MMWFDSINK_PRINT_STATE(wfd_sink);
+
+       wfd_sink_debug_fleave();
+
+       return MM_ERROR_NONE;
+}
+
+static int
+__mm_wfd_sink_set_pipeline_state(mm_wfd_sink_t *wfd_sink, GstState state, gboolean async)
+{
+       GstStateChangeReturn result = GST_STATE_CHANGE_FAILURE;
+       GstState cur_state = GST_STATE_VOID_PENDING;
+       GstState pending_state = GST_STATE_VOID_PENDING;
+
+       wfd_sink_debug_fenter();
+
+       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);
+
+       wfd_sink_return_val_if_fail(state > GST_STATE_VOID_PENDING, MM_ERROR_WFD_INVALID_ARGUMENT);
+
+       wfd_sink_debug("try to set %s state ", 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) {
+               wfd_sink_error("fail to set %s state....", gst_element_state_get_name(state));
+               return MM_ERROR_WFD_INTERNAL;
+       }
+
+       if (!async) {
+               wfd_sink_debug("wait for changing state is completed ");
+
+               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) {
+                       wfd_sink_error("fail to get state within %d seconds....", wfd_sink->ini.state_change_timeout);
+
+                       __mm_wfd_sink_dump_pipeline_state(wfd_sink);
+
+                       return MM_ERROR_WFD_INTERNAL;
+               } else if (result == GST_STATE_CHANGE_NO_PREROLL) {
+                       wfd_sink_debug("successfully changed state but is not able to provide data yet");
+               }
+
+               wfd_sink_debug("cur state is %s, pending state is %s",
+                                       gst_element_state_get_name(cur_state),
+                                       gst_element_state_get_name(pending_state));
+       }
+
+
+       wfd_sink_debug_fleave();
+
+       return MM_ERROR_NONE;
+}
+
+static void
+_mm_wfd_sink_reset_basetime(mm_wfd_sink_t *wfd_sink)
+{
+       GstClockTime base_time = GST_CLOCK_TIME_NONE;
+       int i;
+
+       wfd_sink_debug_fenter();
+
+       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)) {
+
+               wfd_sink_debug("set pipeline base_time as now [%"GST_TIME_FORMAT"]", GST_TIME_ARGS(base_time));
+
+               for (i = 0; i < WFD_SINK_M_NUM; i++) {
+                       if (wfd_sink->pipeline->mainbin[i].gst)
+                               gst_element_set_base_time(GST_ELEMENT_CAST(wfd_sink->pipeline->mainbin[i].gst), base_time);
+               }
+
+               if (wfd_sink->pipeline->v_decodebin) {
+                       for (i = 0; i < WFD_SINK_V_D_NUM; i++) {
+                               if (wfd_sink->pipeline->v_decodebin[i].gst)
+                                       gst_element_set_base_time(GST_ELEMENT_CAST(wfd_sink->pipeline->v_decodebin[i].gst), base_time);
+                       }
+               }
+
+               if (wfd_sink->pipeline->v_sinkbin) {
+                       for (i = 0; i < WFD_SINK_V_S_NUM; i++) {
+                               if (wfd_sink->pipeline->v_sinkbin[i].gst)
+                                       gst_element_set_base_time(GST_ELEMENT_CAST(wfd_sink->pipeline->v_sinkbin[i].gst), base_time);
+                       }
+               }
+
+               if (wfd_sink->pipeline->a_decodebin) {
+                       for (i = 0; i < WFD_SINK_A_D_NUM; i++) {
+                               if (wfd_sink->pipeline->a_decodebin[i].gst)
+                                       gst_element_set_base_time(GST_ELEMENT_CAST(wfd_sink->pipeline->a_decodebin[i].gst), base_time);
+                       }
+               }
+
+               if (wfd_sink->pipeline->a_sinkbin) {
+                       for (i = 0; i < WFD_SINK_A_S_NUM; i++) {
+                               if (wfd_sink->pipeline->a_sinkbin[i].gst)
+                                       gst_element_set_base_time(GST_ELEMENT_CAST(wfd_sink->pipeline->a_sinkbin[i].gst), base_time);
+                       }
+               }
+
+               wfd_sink->need_to_reset_basetime = FALSE;
+       }
+
+       wfd_sink_debug_fleave();
+
+       return;
+}
+
+int
+__mm_wfd_sink_prepare_video_pipeline(mm_wfd_sink_t *wfd_sink)
+{
+       GstElement *bin = NULL;
+
+       wfd_sink_debug_fenter();
+
+       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);
+
+       /* check video decodebin is linked */
+       if (!wfd_sink->video_decodebin_is_linked) {
+               /* check video decodebin is created */
+               if (wfd_sink->pipeline->v_decodebin == NULL) {
+                       if (MM_ERROR_NONE != __mm_wfd_sink_create_video_decodebin(wfd_sink)) {
+                               wfd_sink_error("failed to create video decodebin....");
+                               goto ERROR;
+                       }
+               }
+
+               if (MM_ERROR_NONE != __mm_wfd_sink_link_video_decodebin(wfd_sink)) {
+                       wfd_sink_error("failed to link video decodebin.....");
+                       goto ERROR;
+               }
+       }
+
+       /* check video sinkbin is created */
+       if (wfd_sink->pipeline->v_sinkbin == NULL) {
+               if (MM_ERROR_NONE != __mm_wfd_sink_create_video_sinkbin(wfd_sink)) {
+                       wfd_sink_error("failed to create video sinkbin....");
+                       goto ERROR;
+               }
+       }
+
+       /* set video decodebin state as READY */
+       if (wfd_sink->pipeline->v_decodebin && wfd_sink->pipeline->v_decodebin[WFD_SINK_V_D_BIN].gst) {
+               bin = wfd_sink->pipeline->v_decodebin[WFD_SINK_V_D_BIN].gst;
+               if (GST_STATE(bin) <= GST_STATE_NULL) {
+                       if (GST_STATE_CHANGE_FAILURE == gst_element_set_state(bin, GST_STATE_READY)) {
+                               wfd_sink_error("failed to set state(READY) to video decodebin");
+                               goto ERROR;
+                       }
+               }
+       } else {
+               wfd_sink_warning("going on without video decodebin....");
+       }
+
+       /* set video sinkbin state as READY */
+       if (wfd_sink->pipeline->v_sinkbin && wfd_sink->pipeline->v_sinkbin[WFD_SINK_V_S_BIN].gst) {
+               bin = wfd_sink->pipeline->v_sinkbin[WFD_SINK_V_S_BIN].gst;
+               if (GST_STATE(bin) <= GST_STATE_NULL) {
+                       if (GST_STATE_CHANGE_FAILURE == gst_element_set_state(bin, GST_STATE_READY)) {
+                               wfd_sink_error("failed to set state(READY) to video sinkbin");
+                               goto ERROR;
+                       }
+               }
+       } else {
+               wfd_sink_warning("going on without video sinkbin....");
+       }
+
+       wfd_sink_debug_fleave();
+
+       return MM_ERROR_NONE;
+
+       /* ERRORS */
+ERROR:
+       /* need to notify to app */
+       MMWFDSINK_POST_MESSAGE(wfd_sink,
+                                               MM_ERROR_WFD_INTERNAL,
+                                               MMWFDSINK_CURRENT_STATE(wfd_sink));
+
+       return MM_ERROR_WFD_INTERNAL;
+}
+
+int __mm_wfd_sink_prepare_audio_pipeline(mm_wfd_sink_t *wfd_sink)
+{
+       GstElement *bin  = NULL;
+
+       wfd_sink_debug_fenter();
+
+       wfd_sink_return_val_if_fail(wfd_sink &&
+                                               wfd_sink->pipeline,
+                                               MM_ERROR_WFD_NOT_INITIALIZED);
+
+       /* check audio decodebin is linked */
+       if (!wfd_sink->audio_decodebin_is_linked) {
+               /* check audio decodebin is created */
+               if (wfd_sink->pipeline->a_decodebin == NULL) {
+                       if (MM_ERROR_NONE != __mm_wfd_sink_create_audio_decodebin(wfd_sink)) {
+                               wfd_sink_error("failed to create audio decodebin....");
+                               goto ERROR;
+                       }
+               }
+
+               if (MM_ERROR_NONE != __mm_wfd_sink_link_audio_decodebin(wfd_sink)) {
+                       wfd_sink_error("failed to link audio decodebin.....");
+                       goto ERROR;
+               }
+       }
+
+       /* check audio sinkbin is created */
+       if (wfd_sink->pipeline->a_sinkbin == NULL) {
+               if (MM_ERROR_NONE != __mm_wfd_sink_create_audio_sinkbin(wfd_sink)) {
+                       wfd_sink_error("failed to create audio sinkbin....");
+                       goto ERROR;
+               }
+       }
+
+       /* set audio decodebin state as READY */
+       if (wfd_sink->pipeline->a_decodebin && wfd_sink->pipeline->a_decodebin[WFD_SINK_A_D_BIN].gst) {
+               bin  = wfd_sink->pipeline->a_decodebin[WFD_SINK_A_D_BIN].gst;
+               if (GST_STATE(bin) <= GST_STATE_NULL) {
+                       if (GST_STATE_CHANGE_FAILURE == gst_element_set_state(bin, GST_STATE_READY)) {
+                               wfd_sink_error("failed to set state(READY) to audio decodebin");
+                               goto ERROR;
+                       }
+               }
+       } else {
+               wfd_sink_warning("going on without audio decodebin....");
+       }
+
+       /* set audio sinkbin state as READY */
+       if (wfd_sink->pipeline->a_sinkbin && wfd_sink->pipeline->a_sinkbin[WFD_SINK_A_S_BIN].gst) {
+               bin = wfd_sink->pipeline->a_sinkbin[WFD_SINK_A_S_BIN].gst;
+               if (GST_STATE(bin) <= GST_STATE_NULL) {
+                       if (GST_STATE_CHANGE_FAILURE == gst_element_set_state(bin , GST_STATE_READY)) {
+                               wfd_sink_error("failed to set state(READY) to audio sinkbin");
+                               goto ERROR;
+                       }
+               }
+       } else {
+               wfd_sink_warning("going on without audio sinkbin....");
+       }
+
+       wfd_sink_debug_fleave();
+
+       return MM_ERROR_NONE;
+
+       /* ERRORS */
+ERROR:
+       /* need to notify to app */
+       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;
+
+       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");
+               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->v_sinkbin[WFD_SINK_V_S_BIN].gst);
+       else if (g_strrstr(GST_OBJECT_NAME(pad), "audio"))
+               base_time = gst_element_get_base_time(wfd_sink->pipeline->a_sinkbin[WFD_SINK_A_S_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"", 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_warning("buffer timestamp is invalid.");
+               return GST_PAD_PROBE_OK;
+       }
+
+       if (g_strrstr(GST_OBJECT_NAME(pad), "audio")) {
+               if (wfd_sink->pipeline && wfd_sink->pipeline->a_sinkbin && wfd_sink->pipeline->a_sinkbin[WFD_SINK_A_S_SINK].gst)
+                       g_object_get(G_OBJECT(wfd_sink->pipeline->a_sinkbin[WFD_SINK_A_S_SINK].gst), "ts-offset", &ts_offset, NULL);
+       } else if (g_strrstr(GST_OBJECT_NAME(pad), "video")) {
+               if (wfd_sink->pipeline && wfd_sink->pipeline->v_sinkbin && wfd_sink->pipeline->v_sinkbin[WFD_SINK_V_S_SINK].gst)
+                       g_object_get(G_OBJECT(wfd_sink->pipeline->v_sinkbin[WFD_SINK_V_S_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 "",
+                                               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.. ");
+               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) ", 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"",
+                                                       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) ", 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"",
+                                                       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 ",
+                                               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")",
+                                               minus_compensation ? "-" : "", avgrage_gap_diff,
+                                               GST_TIME_ARGS(ts_offset), GST_TIME_ARGS(running_time));
+
+                               if (wfd_sink->pipeline && wfd_sink->pipeline->a_sinkbin && wfd_sink->pipeline->a_sinkbin[WFD_SINK_A_S_SINK].gst)
+                                       g_object_set(G_OBJECT(wfd_sink->pipeline->a_sinkbin[WFD_SINK_A_S_SINK].gst), "ts-offset", (gint64)ts_offset, NULL);
+                               if (wfd_sink->pipeline && wfd_sink->pipeline->v_sinkbin && wfd_sink->pipeline->v_sinkbin[WFD_SINK_V_S_SINK].gst)
+                                       g_object_set(G_OBJECT(wfd_sink->pipeline->v_sinkbin[WFD_SINK_V_S_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 ")",
+                                               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,
+                                       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)
+{
+       mm_wfd_sink_t *wfd_sink = (mm_wfd_sink_t *)data;
+       gchar *name = gst_pad_get_name(pad);
+       GstElement *pipeline = NULL;
+       GstElement *decodebin = NULL;
+       GstElement *sinkbin = NULL;
+       GstPad *sinkpad = NULL;
+       GstPad *srcpad = NULL;
+
+       wfd_sink_debug_fenter();
+
+       wfd_sink_return_if_fail(wfd_sink &&
+                                       wfd_sink->pipeline &&
+                                       wfd_sink->pipeline->mainbin &&
+                                       wfd_sink->pipeline->mainbin[WFD_SINK_M_PIPE].gst);
+
+       pipeline = wfd_sink->pipeline->mainbin[WFD_SINK_M_PIPE].gst;
+
+       /* take decodebin/sinkbin */
+       if (name[0] == 'v') {
+               wfd_sink_debug("=========== >>>>>>>>>> Received VIDEO pad...");
+
+               MMWFDSINK_PAD_PROBE(wfd_sink, pad, NULL,  NULL);
+
+               gst_pad_add_probe(pad,
+                                       GST_PAD_PROBE_TYPE_BUFFER,
+                                       _mm_wfd_sink_check_running_time,
+                                       (gpointer)wfd_sink,
+                                       NULL);
+
+               if (MM_ERROR_NONE != __mm_wfd_sink_prepare_video_pipeline(wfd_sink)) {
+                       wfd_sink_error("failed to prepare video pipeline....");
+                       goto ERROR;
+               }
+
+               if (wfd_sink->pipeline->v_decodebin && wfd_sink->pipeline->v_decodebin[WFD_SINK_V_D_BIN].gst)
+                       decodebin = wfd_sink->pipeline->v_decodebin[WFD_SINK_V_D_BIN].gst;
+               if (wfd_sink->pipeline->v_sinkbin && wfd_sink->pipeline->v_sinkbin[WFD_SINK_V_S_BIN].gst)
+                       sinkbin = wfd_sink->pipeline->v_sinkbin[WFD_SINK_V_S_BIN].gst;
+       } else if (name[0] == 'a') {
+               wfd_sink_debug("=========== >>>>>>>>>> Received AUDIO pad...");
+
+               MMWFDSINK_PAD_PROBE(wfd_sink, pad, NULL,  NULL);
+
+               gst_pad_add_probe(pad,
+                                       GST_PAD_PROBE_TYPE_BUFFER,
+                                       _mm_wfd_sink_check_running_time,
+                                       (gpointer)wfd_sink,
+                                       NULL);
+
+               if (MM_ERROR_NONE != __mm_wfd_sink_prepare_audio_pipeline(wfd_sink)) {
+                       wfd_sink_error("failed to prepare audio pipeline....");
+                       goto ERROR;
+               }
+
+               if (wfd_sink->pipeline->a_decodebin && wfd_sink->pipeline->a_decodebin[WFD_SINK_A_D_BIN].gst)
+                       decodebin = wfd_sink->pipeline->a_decodebin[WFD_SINK_A_D_BIN].gst;
+               if (wfd_sink->pipeline->a_sinkbin && wfd_sink->pipeline->a_sinkbin[WFD_SINK_A_S_BIN].gst)
+                       sinkbin = wfd_sink->pipeline->a_sinkbin[WFD_SINK_A_S_BIN].gst;
+       } else {
+               wfd_sink_error("unexceptable pad is added!!!");
+               return;
+       }
+
+       srcpad = gst_object_ref(pad);
+
+       /* add decodebin and link */
+       if (decodebin) {
+               if (!gst_bin_add(GST_BIN(pipeline), decodebin)) {
+                       wfd_sink_error("failed to add %s to pipeline",
+                                       GST_STR_NULL(GST_ELEMENT_NAME(decodebin)));
+                       goto ERROR;
+               }
+
+               sinkpad = gst_element_get_static_pad(decodebin, "sink");
+               if (!sinkpad) {
+                       wfd_sink_error("failed to get sink pad from %s",
+                                       GST_STR_NULL(GST_ELEMENT_NAME(decodebin)));
+                       goto ERROR;
+               }
+
+               if (GST_PAD_LINK_OK != gst_pad_link(srcpad, sinkpad)) {
+                       wfd_sink_error("failed to link %s and %s",
+                                       GST_STR_NULL(GST_PAD_NAME(srcpad)),
+                                       GST_STR_NULL(GST_PAD_NAME(sinkpad)));
+                       goto ERROR;
+               }
+               gst_object_unref(GST_OBJECT(srcpad));
+               srcpad = NULL;
+               gst_object_unref(GST_OBJECT(sinkpad));
+               sinkpad = NULL;
+
+               srcpad = gst_element_get_static_pad(decodebin, "src");
+               if (!srcpad) {
+                       wfd_sink_error("failed to get src pad from %s",
+                                       GST_STR_NULL(GST_ELEMENT_NAME(decodebin)));
+                       goto ERROR;
+               }
+       } else {
+               wfd_sink_warning("going on without decodebin...");
+       }
+
+       /* add sinkbin and link */
+       if (sinkbin) {
+               if (!gst_bin_add(GST_BIN(pipeline), sinkbin)) {
+                       wfd_sink_error("failed to add %s to pipeline",
+                                       GST_STR_NULL(GST_ELEMENT_NAME(sinkbin)));
+                       goto ERROR;
+               }
+
+               sinkpad = gst_element_get_static_pad(sinkbin, "sink");
+               if (!sinkpad) {
+                       wfd_sink_error("failed to get sink pad from %s",
+                                       GST_STR_NULL(GST_ELEMENT_NAME(sinkbin)));
+                       goto ERROR;
+               }
+
+               if (GST_PAD_LINK_OK != gst_pad_link(srcpad, sinkpad)) {
+                       wfd_sink_error("failed to link %s and %s",
+                                       GST_STR_NULL(GST_PAD_NAME(srcpad)),
+                                       GST_STR_NULL(GST_PAD_NAME(sinkpad)));
+                       goto ERROR;
+               }
+               gst_object_unref(GST_OBJECT(srcpad));
+               srcpad = NULL;
+               gst_object_unref(GST_OBJECT(sinkpad));
+               sinkpad = NULL;
+       } else {
+               wfd_sink_error("there is no sinkbin...");
+               goto ERROR;
+       }
+
+
+       /* run */
+       if (decodebin) {
+               if (!gst_element_sync_state_with_parent(GST_ELEMENT_CAST(decodebin))) {
+                       wfd_sink_error("failed to sync %s state with parent",
+                               GST_STR_NULL(GST_PAD_NAME(decodebin)));
+                       goto ERROR;
+               }
+       }
+
+       if (sinkbin) {
+               if (!gst_element_sync_state_with_parent(GST_ELEMENT_CAST(sinkbin))) {
+                       wfd_sink_error("failed to sync %s state with parent",
+                               GST_STR_NULL(GST_PAD_NAME(sinkbin)));
+                       goto ERROR;
+               }
+       }
+
+       if (name[0] == 'v') {
+               MMWFDSINK_GENERATE_DOT_IF_ENABLED(wfd_sink, "video-pad-added-pipeline");
+       } else if (name[0] == 'a') {
+               MMWFDSINK_GENERATE_DOT_IF_ENABLED(wfd_sink, "audio-pad-added-pipeline");
+       }
+
+       MMWFDSINK_FREEIF(name);
+
+       wfd_sink_debug_fleave();
+
+       return;
+
+       /* ERRORS */
+ERROR:
+       MMWFDSINK_FREEIF(name);
+
+       if (srcpad)
+               gst_object_unref(GST_OBJECT(srcpad));
+       srcpad = NULL;
+
+       if (sinkpad)
+               gst_object_unref(GST_OBJECT(sinkpad));
+       sinkpad = NULL;
+
+       /* need to notify to app */
+       MMWFDSINK_POST_MESSAGE(wfd_sink,
+                                                       MM_ERROR_WFD_INTERNAL,
+                                                       MMWFDSINK_CURRENT_STATE(wfd_sink));
+
+       return;
+}
+
+static void
+__mm_wfd_sink_change_av_format(GstElement *wfdsrc, gpointer *need_to_flush, gpointer data)
+{
+       mm_wfd_sink_t *wfd_sink = (mm_wfd_sink_t *)data;
+
+       wfd_sink_debug_fenter();
+
+       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) {
+               wfd_sink_debug("need to flush pipeline");
+               *need_to_flush = (gpointer) TRUE;
+       } else {
+               wfd_sink_debug("don't need to flush pipeline");
+               *need_to_flush = (gpointer) FALSE;
+       }
+
+
+       wfd_sink_debug_fleave();
+}
+
+
+static void
+__mm_wfd_sink_update_stream_info(GstElement *wfdsrc, GstStructure *str, gpointer data)
+{
+       mm_wfd_sink_t *wfd_sink = (mm_wfd_sink_t *)data;
+       MMWFDSinkStreamInfo *stream_info = NULL;
+       gint is_valid_audio_format = FALSE;
+       gint is_valid_video_format = FALSE;
+       gint audio_codec = MM_WFD_SINK_AUDIO_CODEC_NONE;
+       gint video_codec = MM_WFD_SINK_VIDEO_CODEC_NONE;
+       gchar *audio_format;
+       gchar *video_format;
+
+       wfd_sink_debug_fenter();
+
+       wfd_sink_return_if_fail(str && GST_IS_STRUCTURE(str));
+       wfd_sink_return_if_fail(wfd_sink);
+
+       stream_info = &wfd_sink->stream_info;
+
+       audio_codec = wfd_sink->stream_info.audio_stream_info.codec;
+       video_codec = wfd_sink->stream_info.video_stream_info.codec;
+
+       if (gst_structure_has_field(str, "audio_format")) {
+               is_valid_audio_format = TRUE;
+               audio_format = g_strdup(gst_structure_get_string(str, "audio_format"));
+               if (g_strrstr(audio_format, "AAC"))
+                       stream_info->audio_stream_info.codec = MM_WFD_SINK_AUDIO_CODEC_AAC;
+               else if (g_strrstr(audio_format, "AC3"))
+                       stream_info->audio_stream_info.codec = MM_WFD_SINK_AUDIO_CODEC_AC3;
+               else if (g_strrstr(audio_format, "LPCM"))
+                       stream_info->audio_stream_info.codec = MM_WFD_SINK_AUDIO_CODEC_LPCM;
+               else {
+                       wfd_sink_error("invalid audio format(%s)...", audio_format);
+                       is_valid_audio_format = FALSE;
+               }
+
+               if (is_valid_audio_format == TRUE) {
+                       if (gst_structure_has_field(str, "audio_rate"))
+                               gst_structure_get_int(str, "audio_rate", &stream_info->audio_stream_info.sample_rate);
+                       if (gst_structure_has_field(str, "audio_channels"))
+                               gst_structure_get_int(str, "audio_channels", &stream_info->audio_stream_info.channels);
+                       if (gst_structure_has_field(str, "audio_bitwidth"))
+                               gst_structure_get_int(str, "audio_bitwidth", &stream_info->audio_stream_info.bitwidth);
+
+                       if (audio_codec != MM_WFD_SINK_AUDIO_CODEC_NONE) {
+                               if (audio_codec != stream_info->audio_stream_info.codec) {
+                                       wfd_sink_debug("audio codec is changed...need to change audio decodebin");
+                               }
+                       } else {
+                               WFD_SINK_MANAGER_APPEND_CMD(wfd_sink, WFD_SINK_MANAGER_CMD_PREPARE_A_PIPELINE);
+                       }
+
+                       wfd_sink_debug("audio_format : %s \n \t rate :  %d \n \t channels :  %d \n \t bitwidth :  %d \n \t",
+                                               audio_format,
+                                               stream_info->audio_stream_info.sample_rate,
+                                               stream_info->audio_stream_info.channels,
+                                               stream_info->audio_stream_info.bitwidth);
+               }
+       }
+
+       if (gst_structure_has_field(str, "video_format")) {
+               is_valid_video_format = TRUE;
+               video_format = g_strdup(gst_structure_get_string(str, "video_format"));
+               if (!g_strrstr(video_format, "H264")) {
+                       wfd_sink_error("invalid video format(%s)...", video_format);
+                       is_valid_video_format = FALSE;
+               }
+
+               if (is_valid_video_format == TRUE) {
+                       stream_info->video_stream_info.codec = MM_WFD_SINK_VIDEO_CODEC_H264;
+
+                       if (gst_structure_has_field(str, "video_width"))
+                               gst_structure_get_int(str, "video_width", &stream_info->video_stream_info.width);
+                       if (gst_structure_has_field(str, "video_height"))
+                               gst_structure_get_int(str, "video_height", &stream_info->video_stream_info.height);
+                       if (gst_structure_has_field(str, "video_framerate"))
+                               gst_structure_get_int(str, "video_framerate", &stream_info->video_stream_info.frame_rate);
+
+                       if (video_codec != MM_WFD_SINK_AUDIO_CODEC_NONE) {
+                               if (video_codec != stream_info->video_stream_info.codec) {
+                                       wfd_sink_debug("video codec is changed...need to change video decodebin");
+                               }
+                       } else {
+                               WFD_SINK_MANAGER_APPEND_CMD(wfd_sink, WFD_SINK_MANAGER_CMD_PREPARE_V_PIPELINE);
+                       }
+
+                       wfd_sink_debug("video_format : %s \n \t width :  %d \n \t height :  %d \n \t frame_rate :  %d \n \t",
+                                               video_format,
+                                               stream_info->video_stream_info.width,
+                                               stream_info->video_stream_info.height,
+                                               stream_info->video_stream_info.frame_rate);
+               }
+       }
+
+       WFD_SINK_MANAGER_SIGNAL_CMD(wfd_sink);
+
+       wfd_sink_debug_fleave();
+}
+
+static int __mm_wfd_sink_prepare_source(mm_wfd_sink_t *wfd_sink, GstElement *wfdsrc)
+{
+       GstStructure *audio_param = NULL;
+       GstStructure *video_param = NULL;
+       GstStructure *hdcp_param = NULL;
+       gint hdcp_version = 0;
+       gint hdcp_port = 0;
+       guint CEA_resolution = 0;
+       guint VESA_resolution = 0;
+       guint HH_resolution = 0;
+       GObjectClass *klass;
+
+       wfd_sink_debug_fenter();
+
+       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(wfdsrc, MM_ERROR_WFD_NOT_INITIALIZED);
+
+       klass = G_OBJECT_GET_CLASS(G_OBJECT(wfdsrc));
+
+       g_object_set(G_OBJECT(wfdsrc), "debug", wfd_sink->ini.set_debug_property, NULL);
+       g_object_set(G_OBJECT(wfdsrc), "enable-pad-probe", wfd_sink->ini.enable_wfdsrc_pad_probe, NULL);
+       if (g_object_class_find_property(klass, "udp-buffer-size"))
+               g_object_set(G_OBJECT(wfdsrc), "udp-buffer-size", 2097152, NULL);
+       if (g_object_class_find_property(klass, "do-request"))
+               g_object_set(G_OBJECT(wfdsrc), "do-request", wfd_sink->ini.enable_retransmission, NULL);
+       if (g_object_class_find_property(klass, "latency"))
+               g_object_set(G_OBJECT(wfdsrc), "latency", wfd_sink->ini.jitter_buffer_latency, NULL);
+
+       audio_param = gst_structure_new("audio_param",
+                                                               "audio_codec", G_TYPE_UINT, wfd_sink->ini.audio_codec,
+                                                               "audio_latency", G_TYPE_UINT, wfd_sink->ini.audio_latency,
+                                                               "audio_channels", G_TYPE_UINT, wfd_sink->ini.audio_channel,
+                                                               "audio_sampling_frequency", G_TYPE_UINT, wfd_sink->ini.audio_sampling_frequency,
+                                                               NULL);
+
+       CEA_resolution = wfd_sink->ini.video_cea_support;
+       VESA_resolution = wfd_sink->ini.video_vesa_support;
+       HH_resolution =  wfd_sink->ini.video_hh_support;
+
+       __mm_wfd_sink_prepare_video_resolution(wfd_sink->supportive_resolution, &CEA_resolution, &VESA_resolution, &HH_resolution);
+
+       wfd_sink_debug("set video resolution CEA[%x] VESA[%x] HH[%x]", CEA_resolution, VESA_resolution, HH_resolution);
+
+       video_param = gst_structure_new("video_param",
+                                                       "video_codec", G_TYPE_UINT, wfd_sink->ini.video_codec,
+                                                       "video_native_resolution", G_TYPE_UINT, wfd_sink->ini.video_native_resolution,
+                                                       "video_cea_support", G_TYPE_UINT, CEA_resolution,
+                                                       "video_vesa_support", G_TYPE_UINT, VESA_resolution,
+                                                       "video_hh_support", G_TYPE_UINT, HH_resolution,
+                                                       "video_profile", G_TYPE_UINT, wfd_sink->ini.video_profile,
+                                                       "video_level", G_TYPE_UINT, wfd_sink->ini.video_level,
+                                                       "video_latency", G_TYPE_UINT, wfd_sink->ini.video_latency,
+                                                       "video_vertical_resolution", G_TYPE_INT, wfd_sink->ini.video_vertical_resolution,
+                                                       "video_horizontal_resolution", G_TYPE_INT, wfd_sink->ini.video_horizontal_resolution,
+                                                       "video_minimum_slicing", G_TYPE_INT, wfd_sink->ini.video_minimum_slicing,
+                                                       "video_slice_enc_param", G_TYPE_INT, wfd_sink->ini.video_slice_enc_param,
+                                                       "video_framerate_control_support", G_TYPE_INT, wfd_sink->ini.video_framerate_control_support,
+                                                       NULL);
+
+       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);
+       wfd_sink_debug("set hdcp version %d with %d port", hdcp_version, hdcp_port);
+
+       hdcp_param = gst_structure_new("hdcp_param",
+                                                       "hdcp_version", G_TYPE_INT, hdcp_version,
+                                                       "hdcp_port_no", G_TYPE_INT, hdcp_port,
+                                                       NULL);
+
+       g_object_set(G_OBJECT(wfdsrc), "audio-param", audio_param, NULL);
+       g_object_set(G_OBJECT(wfdsrc), "video-param", video_param, NULL);
+       g_object_set(G_OBJECT(wfdsrc), "hdcp-param", hdcp_param, NULL);
+
+       g_signal_connect(wfdsrc, "update-media-info", G_CALLBACK(__mm_wfd_sink_update_stream_info), wfd_sink);
+
+       g_signal_connect(wfdsrc, "change-av-format", G_CALLBACK(__mm_wfd_sink_change_av_format), wfd_sink);
+
+       wfd_sink_debug_fleave();
+
+       return MM_ERROR_NONE;
+}
+
+static int __mm_wfd_sink_prepare_demux(mm_wfd_sink_t *wfd_sink, GstElement *demux)
+{
+       wfd_sink_debug_fenter();
+
+       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);
+
+       wfd_sink_debug_fleave();
+
+       return MM_ERROR_NONE;
+}
+
+static void __mm_wfd_sink_queue_overrun(GstElement *element, gpointer u_data)
+{
+       wfd_sink_debug_fenter();
+
+       return_if_fail(element);
+
+       wfd_sink_warning("%s is overrun",
+                                       GST_STR_NULL(GST_ELEMENT_NAME(element)));
+
+       wfd_sink_debug_fleave();
+
+       return;
+}
+
+static void __mm_wfd_sink_prepare_queue(mm_wfd_sink_t *wfd_sink, GstElement *queue)
+{
+       wfd_sink_debug_fenter();
+
+       wfd_sink_return_if_fail(wfd_sink);
+       wfd_sink_return_if_fail(queue);
+
+       /* set maximum buffer size of queue as 3sec */
+       g_object_set(G_OBJECT(queue), "max-size-bytes", 0, NULL);
+       g_object_set(G_OBJECT(queue), "max-size-buffers", 0, NULL);
+       g_object_set(G_OBJECT(queue), "max-size-time", (guint64)3000000000ULL, NULL);
+       g_signal_connect(queue, "overrun", G_CALLBACK(__mm_wfd_sink_queue_overrun), wfd_sink);
+
+       wfd_sink_debug_fleave();
+
+       return;
+}
+
+
+static int __mm_wfd_sink_create_pipeline(mm_wfd_sink_t *wfd_sink)
+{
+       MMWFDSinkGstElement *mainbin = NULL;
+       GList *element_bucket = NULL;
+       GstBus  *bus = NULL;
+       int i;
+
+       wfd_sink_debug_fenter();
+
+       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));
+       if (wfd_sink->pipeline == NULL)
+               goto CREATE_ERROR;
+
+       memset(wfd_sink->pipeline, 0, sizeof(MMWFDSinkGstPipelineInfo));
+
+       /* create mainbin */
+       mainbin = (MMWFDSinkGstElement *) g_malloc0(sizeof(MMWFDSinkGstElement) * WFD_SINK_M_NUM);
+       if (mainbin == NULL)
+               goto CREATE_ERROR;
+
+       memset(mainbin, 0, sizeof(MMWFDSinkGstElement) * WFD_SINK_M_NUM);
+
+       /* create pipeline */
+       mainbin[WFD_SINK_M_PIPE].id = WFD_SINK_M_PIPE;
+       mainbin[WFD_SINK_M_PIPE].gst = gst_pipeline_new("wfdsink");
+       if (!mainbin[WFD_SINK_M_PIPE].gst) {
+               wfd_sink_error("failed to create pipeline");
+               goto CREATE_ERROR;
+       }
+
+       /* create wfdsrc */
+       MMWFDSINK_CREATE_ELEMENT(mainbin, WFD_SINK_M_SRC, wfd_sink->ini.name_of_source, "wfdsink_source", TRUE);
+       MMWFDSINK_PAD_PROBE(wfd_sink, NULL, mainbin[WFD_SINK_M_SRC].gst,  "src");
+       if (mainbin[WFD_SINK_M_SRC].gst) {
+               if (MM_ERROR_NONE != __mm_wfd_sink_prepare_source(wfd_sink, mainbin[WFD_SINK_M_SRC].gst)) {
+                       wfd_sink_error("failed to prepare wfdsrc...");
+                       goto CREATE_ERROR;
+               }
+       }
+
+       /* create rtpmp2tdepay */
+       MMWFDSINK_CREATE_ELEMENT(mainbin, WFD_SINK_M_DEPAY, "rtpmp2tdepay", "wfdsink_depay", TRUE);
+       MMWFDSINK_PAD_PROBE(wfd_sink, NULL, mainbin[WFD_SINK_M_DEPAY].gst, "src");
+       MMWFDSINK_PAD_PROBE(wfd_sink, NULL, mainbin[WFD_SINK_M_DEPAY].gst, "sink");
+
+       MMWFDSINK_TS_DATA_DUMP(wfd_sink, mainbin[WFD_SINK_M_DEPAY].gst, "src");
+
+       /* 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 (mainbin[WFD_SINK_M_DEMUX].gst) {
+               if (MM_ERROR_NONE != __mm_wfd_sink_prepare_demux(wfd_sink, mainbin[WFD_SINK_M_DEMUX].gst)) {
+                       wfd_sink_error("failed to prepare demux...");
+                       goto CREATE_ERROR;
+               }
+       }
+
+       /* adding created elements to pipeline */
+       if (!__mm_wfd_sink_gst_element_add_bucket_to_bin(GST_BIN_CAST(mainbin[WFD_SINK_M_PIPE].gst), element_bucket, FALSE)) {
+               wfd_sink_error("failed to add elements");
+               goto CREATE_ERROR;
+       }
+
+       /* linking elements in the bucket by added order. */
+       if (__mm_wfd_sink_gst_element_link_bucket(element_bucket) == -1) {
+               wfd_sink_error("failed to link elements");
+               goto CREATE_ERROR;
+       }
+
+       /* connect bus callback */
+       bus = gst_pipeline_get_bus(GST_PIPELINE(mainbin[WFD_SINK_M_PIPE].gst));
+       if (!bus) {
+               wfd_sink_error("cannot get bus from pipeline.");
+               goto CREATE_ERROR;
+       }
+
+       /* add bus message callback*/
+       gst_bus_add_watch(bus, (GstBusFunc)_mm_wfd_sink_msg_callback, wfd_sink);
+
+       /* set sync handler to get tag synchronously */
+       gst_bus_set_sync_handler(bus, _mm_wfd_bus_sync_callback, wfd_sink, NULL);
+
+       g_list_free(element_bucket);
+       gst_object_unref(GST_OBJECT(bus));
+
+       /* now we have completed mainbin. take it */
+       wfd_sink->pipeline->mainbin = mainbin;
+
+       wfd_sink_debug_fleave();
+
+       return MM_ERROR_NONE;
+
+       /* ERRORS */
+CREATE_ERROR:
+       wfd_sink_error("ERROR : releasing pipeline");
+
+       if (element_bucket)
+               g_list_free(element_bucket);
+       element_bucket = NULL;
+
+       /* finished */
+       if (bus)
+               gst_object_unref(GST_OBJECT(bus));
+       bus = NULL;
+
+       /* release element which are not added to bin */
+       for (i = 1; i < WFD_SINK_M_NUM; i++) {  /* NOTE : skip pipeline */
+               if (mainbin != NULL && mainbin[i].gst) {
+                       GstObject *parent = NULL;
+                       parent = gst_element_get_parent(mainbin[i].gst);
+
+                       if (!parent) {
+                               gst_object_unref(GST_OBJECT(mainbin[i].gst));
+                               mainbin[i].gst = NULL;
+                       } else {
+                               gst_object_unref(GST_OBJECT(parent));
+                       }
+               }
+       }
+
+       /* release mainbin with it's childs */
+       if (mainbin != NULL && mainbin[WFD_SINK_M_PIPE].gst)
+               gst_object_unref(GST_OBJECT(mainbin[WFD_SINK_M_PIPE].gst));
+
+       MMWFDSINK_FREEIF(mainbin);
+
+       MMWFDSINK_FREEIF(wfd_sink->pipeline);
+
+       return MM_ERROR_WFD_INTERNAL;
+}
+
+int __mm_wfd_sink_link_audio_decodebin(mm_wfd_sink_t *wfd_sink)
+{
+       MMWFDSinkGstElement *a_decodebin = NULL;
+       MMWFDSinkGstElement *first_element = NULL;
+       MMWFDSinkGstElement *last_element = NULL;
+       GList *element_bucket = NULL;
+       GstPad *sinkpad = NULL;
+       GstPad *srcpad = NULL;
+       GstPad *ghostpad = NULL;
+       GList *first_list = NULL;
+       GList *last_list = NULL;
+
+       wfd_sink_debug_fenter();
+
+       wfd_sink_return_val_if_fail(wfd_sink &&
+                                               wfd_sink->pipeline &&
+                                               wfd_sink->pipeline->a_decodebin &&
+                                               wfd_sink->pipeline->a_decodebin[WFD_SINK_A_D_BIN].gst,
+                                               MM_ERROR_WFD_NOT_INITIALIZED);
+
+       if (wfd_sink->audio_decodebin_is_linked) {
+               wfd_sink_debug("audio decodebin is already linked... nothing to do");
+               return MM_ERROR_NONE;
+       }
+
+       /* take audio decodebin */
+       a_decodebin = wfd_sink->pipeline->a_decodebin;
+
+       /* check audio queue */
+       if (a_decodebin[WFD_SINK_A_D_QUEUE].gst)
+               element_bucket = g_list_append(element_bucket, &a_decodebin[WFD_SINK_A_D_QUEUE]);
+
+       /* check audio hdcp */
+       if (a_decodebin[WFD_SINK_A_D_HDCP].gst)
+               element_bucket = g_list_append(element_bucket, &a_decodebin[WFD_SINK_A_D_HDCP]);
+
+       /* check audio codec */
+       switch (wfd_sink->stream_info.audio_stream_info.codec) {
+               case MM_WFD_SINK_AUDIO_CODEC_LPCM:
+                       if (a_decodebin[WFD_SINK_A_D_LPCM_CONVERTER].gst)
+                               element_bucket = g_list_append(element_bucket, &a_decodebin[WFD_SINK_A_D_LPCM_CONVERTER]);
+                       if (a_decodebin[WFD_SINK_A_D_LPCM_FILTER].gst) {
+                               GstCaps *caps = NULL;
+                               element_bucket = g_list_append(element_bucket, &a_decodebin[WFD_SINK_A_D_LPCM_FILTER]);
+                               caps = gst_caps_new_simple("audio/x-raw",
+                                                                       "rate", G_TYPE_INT, wfd_sink->stream_info.audio_stream_info.sample_rate,
+                                                                       "channels", G_TYPE_INT, wfd_sink->stream_info.audio_stream_info.channels,
+                                                                       "format", G_TYPE_STRING, "S16BE", NULL);
+
+                               g_object_set(G_OBJECT(a_decodebin[WFD_SINK_A_D_LPCM_CONVERTER].gst), "caps", caps, NULL);
+                               gst_object_unref(GST_OBJECT(caps));
+                       }
+                       break;
+
+               case MM_WFD_SINK_AUDIO_CODEC_AAC:
+                       if (a_decodebin[WFD_SINK_A_D_AAC_PARSE].gst)
+                               element_bucket = g_list_append(element_bucket, &a_decodebin[WFD_SINK_A_D_AAC_PARSE]);
+                       if (a_decodebin[WFD_SINK_A_D_AAC_DEC].gst)
+                               element_bucket = g_list_append(element_bucket, &a_decodebin[WFD_SINK_A_D_AAC_DEC]);
+                       break;
+
+               case MM_WFD_SINK_AUDIO_CODEC_AC3:
+                       if (a_decodebin[WFD_SINK_A_D_AC3_PARSE].gst)
+                               element_bucket = g_list_append(element_bucket, &a_decodebin[WFD_SINK_A_D_AC3_PARSE]);
+                       if (a_decodebin[WFD_SINK_A_D_AC3_DEC].gst)
+                               element_bucket = g_list_append(element_bucket, &a_decodebin[WFD_SINK_A_D_AC3_DEC]);
+                       break;
+
+               default:
+                       wfd_sink_error("audio codec is not decied yet. cannot link audio decodebin...");
+                       return MM_ERROR_WFD_INTERNAL;
+                       break;
+       }
+
+       if (element_bucket == NULL) {
+               wfd_sink_error("there are no elements to be linked in the audio decodebin, destroy it");
+               if (MM_ERROR_NONE != __mm_wfd_sink_destroy_audio_decodebin(wfd_sink)) {
+                       wfd_sink_error("failed to destroy audio decodebin");
+                       goto fail_to_link;
+               }
+               goto done;
+       }
+
+       /* adding elements to audio decodebin */
+       if (!__mm_wfd_sink_gst_element_add_bucket_to_bin(GST_BIN_CAST(a_decodebin[WFD_SINK_A_D_BIN].gst), element_bucket, FALSE)) {
+               wfd_sink_error("failed to add elements to audio decodebin");
+               goto fail_to_link;
+       }
+
+       /* linking elements in the bucket by added order. */
+       if (__mm_wfd_sink_gst_element_link_bucket(element_bucket) == -1) {
+               wfd_sink_error("failed to link elements of the audio decodebin");
+               goto fail_to_link;
+       }
+
+       /* get first element's sinkpad for creating ghostpad */
+       first_list = g_list_first(element_bucket);
+       if (first_list == NULL) {
+               wfd_sink_error("failed to get first list of the element_bucket");
+               goto fail_to_link;
+       }
+
+       first_element = (MMWFDSinkGstElement *)first_list->data;
+       if (!first_element) {
+               wfd_sink_error("failed to get first element of the audio decodebin");
+               goto fail_to_link;
+       }
+
+       sinkpad = gst_element_get_static_pad(GST_ELEMENT(first_element->gst), "sink");
+       if (!sinkpad) {
+               wfd_sink_error("failed to get sink pad from element(%s)",
+                       GST_STR_NULL(GST_ELEMENT_NAME(first_element->gst)));
+               goto fail_to_link;
+       }
+
+       ghostpad = gst_ghost_pad_new("sink", sinkpad);
+       if (!ghostpad) {
+               wfd_sink_error("failed to create ghostpad of audio decodebin");
+               goto fail_to_link;
+       }
+
+       if (FALSE == gst_element_add_pad(a_decodebin[WFD_SINK_A_D_BIN].gst, ghostpad)) {
+               wfd_sink_error("failed to add ghostpad to audio decodebin");
+               goto fail_to_link;
+       }
+       gst_object_unref(GST_OBJECT(sinkpad));
+       sinkpad = NULL;
+
+
+       /* get last element's src for creating ghostpad */
+       last_list = g_list_last(element_bucket);
+       if (last_list == NULL) {
+               wfd_sink_error("failed to get last list of the element_bucket");
+               goto fail_to_link;
+       }
+
+       last_element = (MMWFDSinkGstElement *)last_list->data;
+       if (!last_element) {
+               wfd_sink_error("failed to get last element of the audio decodebin");
+               goto fail_to_link;
+       }
+
+       srcpad = gst_element_get_static_pad(GST_ELEMENT(last_element->gst), "src");
+       if (!srcpad) {
+               wfd_sink_error("failed to get src pad from element(%s)",
+                       GST_STR_NULL(GST_ELEMENT_NAME(last_element->gst)));
+               goto fail_to_link;
+       }
+
+       ghostpad = gst_ghost_pad_new("src", srcpad);
+       if (!ghostpad) {
+               wfd_sink_error("failed to create ghostpad of audio decodebin");
+               goto fail_to_link;
+       }
+
+       if (FALSE == gst_element_add_pad(a_decodebin[WFD_SINK_A_D_BIN].gst, ghostpad)) {
+               wfd_sink_error("failed to add ghostpad to audio decodebin");
+               goto fail_to_link;
+       }
+       gst_object_unref(GST_OBJECT(srcpad));
+       srcpad = NULL;
+
+       g_list_free(element_bucket);
+
+done:
+       wfd_sink->audio_decodebin_is_linked = TRUE;
+
+       wfd_sink_debug_fleave();
+
+       return MM_ERROR_NONE;
+
+       /* ERRORS*/
+fail_to_link:
+       if (srcpad)
+               gst_object_unref(GST_OBJECT(srcpad));
+       srcpad = NULL;
+
+       if (sinkpad)
+               gst_object_unref(GST_OBJECT(sinkpad));
+       sinkpad = NULL;
+
+       g_list_free(element_bucket);
+
+       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), "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 int  __mm_wfd_sink_destroy_audio_decodebin(mm_wfd_sink_t *wfd_sink)
+{
+       GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
+       MMWFDSinkGstElement *a_decodebin = 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->a_decodebin &&
+           wfd_sink->pipeline->a_decodebin[WFD_SINK_A_D_BIN].gst) {
+               a_decodebin = wfd_sink->pipeline->a_decodebin;
+       } else {
+               wfd_sink_debug("audio decodebin is not created, nothing to destroy");
+               return MM_ERROR_NONE;
+       }
+
+       parent = gst_element_get_parent(a_decodebin[WFD_SINK_A_D_BIN].gst);
+       if (!parent) {
+               wfd_sink_debug("audio decodebin has no parent.. need to relase by itself");
+
+               if (GST_STATE(a_decodebin[WFD_SINK_A_D_BIN].gst) >= GST_STATE_READY) {
+                       wfd_sink_debug("try to change state of audio decodebin to NULL");
+                       ret = gst_element_set_state(a_decodebin[WFD_SINK_A_D_BIN].gst, GST_STATE_NULL);
+                       if (ret != GST_STATE_CHANGE_SUCCESS) {
+                               wfd_sink_error("failed to change state of audio decodebin to NULL");
+                               return MM_ERROR_WFD_INTERNAL;
+                       }
+               }
+
+               /* release element which are not added to bin */
+               for (i = 1; i < WFD_SINK_A_D_NUM; i++) {        /* NOTE : skip bin */
+                       if (a_decodebin[i].gst) {
+                               parent = gst_element_get_parent(a_decodebin[i].gst);
+                               if (!parent) {
+                                       wfd_sink_debug("unref %s(current ref %d)",
+                                                       GST_STR_NULL(GST_ELEMENT_NAME(a_decodebin[i].gst)),
+                                                       ((GObject *) a_decodebin[i].gst)->ref_count);
+                                       gst_object_unref(GST_OBJECT(a_decodebin[i].gst));
+                                       a_decodebin[i].gst = NULL;
+                               } else {
+                                       wfd_sink_debug("unref %s(current ref %d)",
+                                                       GST_STR_NULL(GST_ELEMENT_NAME(a_decodebin[i].gst)),
+                                                       ((GObject *) a_decodebin[i].gst)->ref_count);
+                                       gst_object_unref(GST_OBJECT(parent));
+                               }
+                       }
+               }
+
+               /* release audio decodebin with it's childs */
+               if (a_decodebin[WFD_SINK_A_D_BIN].gst)
+                       gst_object_unref(GST_OBJECT(a_decodebin[WFD_SINK_A_D_BIN].gst));
+
+       } else {
+               wfd_sink_debug("audio decodebin has parent(%s), unref it ",
+                                       GST_STR_NULL(GST_OBJECT_NAME(GST_OBJECT(parent))));
+
+               gst_object_unref(GST_OBJECT(parent));
+       }
+
+       wfd_sink->audio_decodebin_is_linked = FALSE;
+
+       MMWFDSINK_FREEIF(wfd_sink->pipeline->a_decodebin);
+
+       wfd_sink_debug_fleave();
+
+       return MM_ERROR_NONE;
+}
+
+static int __mm_wfd_sink_create_audio_decodebin(mm_wfd_sink_t *wfd_sink)
+{
+       MMWFDSinkGstElement *a_decodebin = NULL;
+       gint audio_codec = WFD_AUDIO_UNKNOWN;
+       GList *element_bucket = NULL;
+       gboolean link = TRUE;
+       gint i = 0;
+
+       wfd_sink_debug_fenter();
+
+       wfd_sink_return_val_if_fail(wfd_sink &&
+                                               wfd_sink->pipeline,
+                                               MM_ERROR_WFD_NOT_INITIALIZED);
+
+       /* check audio decodebin could be linked now */
+       switch (wfd_sink->stream_info.audio_stream_info.codec) {
+               case MM_WFD_SINK_AUDIO_CODEC_AAC:
+                       audio_codec = WFD_AUDIO_AAC;
+                       link = TRUE;
+                       break;
+               case MM_WFD_SINK_AUDIO_CODEC_AC3:
+                       audio_codec = WFD_AUDIO_AC3;
+                       link = TRUE;
+                       break;
+               case MM_WFD_SINK_AUDIO_CODEC_LPCM:
+                       audio_codec = WFD_AUDIO_LPCM;
+                       link = TRUE;
+                       break;
+               case MM_WFD_SINK_AUDIO_CODEC_NONE:
+               default:
+                       wfd_sink_debug("audio decodebin could NOT be linked now, just create");
+                       audio_codec = wfd_sink->ini.audio_codec;
+                       link = FALSE;
+                       break;
+       }
+
+       /* alloc handles */
+       a_decodebin = (MMWFDSinkGstElement *)g_malloc0(sizeof(MMWFDSinkGstElement) * WFD_SINK_A_D_NUM);
+       if (!a_decodebin) {
+               wfd_sink_error("failed to allocate memory for audio decodebin");
+               return MM_ERROR_WFD_NO_FREE_SPACE;
+       }
+
+       memset(a_decodebin, 0, sizeof(MMWFDSinkGstElement) * WFD_SINK_A_D_NUM);
+
+       /* create audio decodebin */
+       a_decodebin[WFD_SINK_A_D_BIN].id = WFD_SINK_A_D_BIN;
+       a_decodebin[WFD_SINK_A_D_BIN].gst = gst_bin_new("audio_deocebin");
+       if (!a_decodebin[WFD_SINK_A_D_BIN].gst) {
+               wfd_sink_error("failed to create audio decodebin");
+               goto CREATE_ERROR;
+       }
+
+       /* create queue */
+       MMWFDSINK_CREATE_ELEMENT(a_decodebin, WFD_SINK_A_D_QUEUE, "queue", "audio_queue", FALSE);
+       MMWFDSINK_PAD_PROBE(wfd_sink, NULL, a_decodebin[WFD_SINK_A_D_QUEUE].gst,  "sink");
+       if (a_decodebin[WFD_SINK_A_D_QUEUE].gst)
+               __mm_wfd_sink_prepare_queue(wfd_sink, a_decodebin[WFD_SINK_A_D_QUEUE].gst);
+
+       /* create hdcp */
+       MMWFDSINK_CREATE_ELEMENT(a_decodebin, WFD_SINK_A_D_HDCP, wfd_sink->ini.name_of_audio_hdcp, "audio_hdcp", FALSE);
+       MMWFDSINK_PAD_PROBE(wfd_sink, NULL, a_decodebin[WFD_SINK_A_D_HDCP].gst,  "sink");
+
+       /* create codec */
+       audio_codec = wfd_sink->ini.audio_codec;
+       if (audio_codec & WFD_AUDIO_LPCM) {
+               /* create LPCM converter */
+               MMWFDSINK_CREATE_ELEMENT(a_decodebin, WFD_SINK_A_D_LPCM_CONVERTER, wfd_sink->ini.name_of_lpcm_converter, "audio_lpcm_convert", FALSE);
+               MMWFDSINK_PAD_PROBE(wfd_sink, NULL, a_decodebin[WFD_SINK_A_D_LPCM_CONVERTER].gst,  "sink");
+               MMWFDSINK_PAD_PROBE(wfd_sink, NULL, a_decodebin[WFD_SINK_A_D_LPCM_CONVERTER].gst,  "src");
+
+               /* create LPCM filter */
+               MMWFDSINK_CREATE_ELEMENT(a_decodebin, WFD_SINK_A_D_LPCM_FILTER, wfd_sink->ini.name_of_lpcm_filter, "audio_lpcm_filter", FALSE);
+               MMWFDSINK_PAD_PROBE(wfd_sink, NULL, a_decodebin[WFD_SINK_A_D_LPCM_FILTER].gst,  "sink");
+               MMWFDSINK_PAD_PROBE(wfd_sink, NULL, a_decodebin[WFD_SINK_A_D_LPCM_FILTER].gst,  "src");
+       }
+
+       if (audio_codec & WFD_AUDIO_AAC) {
+               /* create AAC parse  */
+               MMWFDSINK_CREATE_ELEMENT(a_decodebin, WFD_SINK_A_D_AAC_PARSE, wfd_sink->ini.name_of_aac_parser, "audio_aac_parser", FALSE);
+               MMWFDSINK_PAD_PROBE(wfd_sink, NULL, a_decodebin[WFD_SINK_A_D_AAC_PARSE].gst,  "sink");
+               MMWFDSINK_PAD_PROBE(wfd_sink, NULL, a_decodebin[WFD_SINK_A_D_AAC_PARSE].gst,  "src");
+
+               /* create AAC decoder  */
+               MMWFDSINK_CREATE_ELEMENT(a_decodebin, WFD_SINK_A_D_AAC_DEC, wfd_sink->ini.name_of_aac_decoder, "audio_aac_dec", FALSE);
+               MMWFDSINK_PAD_PROBE(wfd_sink, NULL, a_decodebin[WFD_SINK_A_D_AAC_DEC].gst,  "sink");
+               MMWFDSINK_PAD_PROBE(wfd_sink, NULL, a_decodebin[WFD_SINK_A_D_AAC_DEC].gst,  "src");
+       }
+
+       if (audio_codec & WFD_AUDIO_AC3) {
+               /* create AC3 parser  */
+               MMWFDSINK_CREATE_ELEMENT(a_decodebin, WFD_SINK_A_D_AC3_PARSE, wfd_sink->ini.name_of_ac3_parser, "audio_ac3_parser", FALSE);
+               MMWFDSINK_PAD_PROBE(wfd_sink, NULL, a_decodebin[WFD_SINK_A_D_AC3_PARSE].gst,  "sink");
+               MMWFDSINK_PAD_PROBE(wfd_sink, NULL, a_decodebin[WFD_SINK_A_D_AC3_PARSE].gst,  "src");
+
+               /* create AC3 decoder  */
+               MMWFDSINK_CREATE_ELEMENT(a_decodebin, WFD_SINK_A_D_AC3_DEC, wfd_sink->ini.name_of_ac3_decoder, "audio_ac3_dec", FALSE);
+               MMWFDSINK_PAD_PROBE(wfd_sink, NULL, a_decodebin[WFD_SINK_A_D_AC3_DEC].gst,  "sink");
+               MMWFDSINK_PAD_PROBE(wfd_sink, NULL, a_decodebin[WFD_SINK_A_D_AC3_DEC].gst,  "src");
+       }
+
+       g_list_free(element_bucket);
+
+       /* take it */
+       wfd_sink->pipeline->a_decodebin = a_decodebin;
+
+       /* link audio decodebin if audio codec is fixed */
+       if (link) {
+               if (MM_ERROR_NONE != __mm_wfd_sink_link_audio_decodebin(wfd_sink)) {
+                       wfd_sink_error("failed to link audio decodebin, destroy audio decodebin");
+                       __mm_wfd_sink_destroy_audio_decodebin(wfd_sink);
+                       return MM_ERROR_WFD_INTERNAL;
+               }
+       }
+
+       wfd_sink_debug_fleave();
+
+       return MM_ERROR_NONE;
+
+CREATE_ERROR:
+       wfd_sink_error("failed to create audio decodebin, release all");
+
+       g_list_free(element_bucket);
+
+       /* release element which are not added to bin */
+       for (i = 1; i < WFD_SINK_A_D_NUM; i++) {        /* NOTE : skip bin */
+               if (a_decodebin != NULL && a_decodebin[i].gst) {
+                       GstObject *parent = NULL;
+                       parent = gst_element_get_parent(a_decodebin[i].gst);
+
+                       if (!parent) {
+                               gst_object_unref(GST_OBJECT(a_decodebin[i].gst));
+                               a_decodebin[i].gst = NULL;
+                       } else {
+                               gst_object_unref(GST_OBJECT(parent));
+                       }
+               }
+       }
+
+       /* release audioo decodebin with it's childs */
+       if (a_decodebin != NULL && a_decodebin[WFD_SINK_A_D_BIN].gst)
+               gst_object_unref(GST_OBJECT(a_decodebin[WFD_SINK_A_D_BIN].gst));
+
+       MMWFDSINK_FREEIF(a_decodebin);
+
+       return MM_ERROR_WFD_INTERNAL;
+}
+
+static int  __mm_wfd_sink_destroy_audio_sinkbin(mm_wfd_sink_t *wfd_sink)
+{
+       GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
+       MMWFDSinkGstElement *a_sinkbin = 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->a_sinkbin &&
+           wfd_sink->pipeline->a_sinkbin[WFD_SINK_A_S_BIN].gst) {
+               a_sinkbin = wfd_sink->pipeline->a_sinkbin;
+       } else {
+               wfd_sink_debug("audio sinkbin is not created, nothing to destroy");
+               return MM_ERROR_NONE;
+       }
+
+       parent = gst_element_get_parent(a_sinkbin[WFD_SINK_A_S_BIN].gst);
+       if (!parent) {
+               wfd_sink_debug("audio decodebin has no parent.. need to relase by itself");
+
+               if (GST_STATE(a_sinkbin[WFD_SINK_A_S_BIN].gst) >= GST_STATE_READY) {
+                       wfd_sink_debug("try to change state of audio decodebin to NULL");
+                       ret = gst_element_set_state(a_sinkbin[WFD_SINK_A_S_BIN].gst, GST_STATE_NULL);
+                       if (ret != GST_STATE_CHANGE_SUCCESS) {
+                               wfd_sink_error("failed to change state of audio decodebin to NULL");
+                               return MM_ERROR_WFD_INTERNAL;
+                       }
+               }
+
+               /* release element which are not added to bin */
+               for (i = 1; i < WFD_SINK_A_S_NUM; i++) {        /* NOTE : skip bin */
+                       if (a_sinkbin[i].gst) {
+                               parent = gst_element_get_parent(a_sinkbin[i].gst);
+                               if (!parent) {
+                                       wfd_sink_debug("unref %s(current ref %d)",
+                                                       GST_STR_NULL(GST_ELEMENT_NAME(a_sinkbin[i].gst)),
+                                                       ((GObject *) a_sinkbin[i].gst)->ref_count);
+                                       gst_object_unref(GST_OBJECT(a_sinkbin[i].gst));
+                                       a_sinkbin[i].gst = NULL;
+                               } else {
+                                       wfd_sink_debug("unref %s(current ref %d)",
+                                                       GST_STR_NULL(GST_ELEMENT_NAME(a_sinkbin[i].gst)),
+                                                       ((GObject *) a_sinkbin[i].gst)->ref_count);
+                                       gst_object_unref(GST_OBJECT(parent));
+                               }
+                       }
+               }
+
+               /* release audio decodebin with it's childs */
+               if (a_sinkbin[WFD_SINK_A_S_BIN].gst)
+                       gst_object_unref(GST_OBJECT(a_sinkbin[WFD_SINK_A_S_BIN].gst));
+
+       } else {
+               wfd_sink_debug("audio sinkbin has parent(%s), unref it ",
+                                       GST_STR_NULL(GST_OBJECT_NAME(GST_OBJECT(parent))));
+
+               gst_object_unref(GST_OBJECT(parent));
+       }
+
+       MMWFDSINK_FREEIF(wfd_sink->pipeline->a_sinkbin);
+
+       wfd_sink_debug_fleave();
+
+       return MM_ERROR_NONE;
+}
+
+static int __mm_wfd_sink_create_audio_sinkbin(mm_wfd_sink_t *wfd_sink)
+{
+       MMWFDSinkGstElement *a_sinkbin = NULL;
+       MMWFDSinkGstElement *first_element = NULL;
+       GList *element_bucket = NULL;
+       GstPad *ghostpad = NULL;
+       GstPad *pad = NULL;
+       gint i = 0;
+       GList *first_list = NULL;
+
+       wfd_sink_debug_fenter();
+
+       wfd_sink_return_val_if_fail(wfd_sink &&
+                                               wfd_sink->pipeline,
+                                               MM_ERROR_WFD_NOT_INITIALIZED);
+
+       /* alloc handles */
+       a_sinkbin = (MMWFDSinkGstElement *)g_malloc0(sizeof(MMWFDSinkGstElement) * WFD_SINK_A_S_NUM);
+       if (!a_sinkbin) {
+               wfd_sink_error("failed to allocate memory for audio sinkbin");
+               return MM_ERROR_WFD_NO_FREE_SPACE;
+       }
+
+       memset(a_sinkbin, 0, sizeof(MMWFDSinkGstElement) * WFD_SINK_A_S_NUM);
+
+       /* create audio sinkbin */
+       a_sinkbin[WFD_SINK_A_S_BIN].id = WFD_SINK_A_S_BIN;
+       a_sinkbin[WFD_SINK_A_S_BIN].gst = gst_bin_new("audio_sinkbin");
+       if (!a_sinkbin[WFD_SINK_A_S_BIN].gst) {
+               wfd_sink_error("failed to create audio sinkbin");
+               goto CREATE_ERROR;
+       }
+
+       /* create resampler */
+       MMWFDSINK_CREATE_ELEMENT(a_sinkbin, WFD_SINK_A_S_RESAMPLER, wfd_sink->ini.name_of_audio_resampler, "audio_resampler", TRUE);
+       MMWFDSINK_PAD_PROBE(wfd_sink, NULL, a_sinkbin[WFD_SINK_A_S_RESAMPLER].gst,  "sink");
+       MMWFDSINK_PAD_PROBE(wfd_sink, NULL, a_sinkbin[WFD_SINK_A_S_RESAMPLER].gst,  "src");
+
+       /* create volume */
+       MMWFDSINK_CREATE_ELEMENT(a_sinkbin, WFD_SINK_A_S_VOLUME, wfd_sink->ini.name_of_audio_volume, "audio_volume", TRUE);
+       MMWFDSINK_PAD_PROBE(wfd_sink, NULL, a_sinkbin[WFD_SINK_A_S_VOLUME].gst,  "sink");
+       MMWFDSINK_PAD_PROBE(wfd_sink, NULL, a_sinkbin[WFD_SINK_A_S_VOLUME].gst,  "src");
+
+       /* create sink */
+       MMWFDSINK_CREATE_ELEMENT(a_sinkbin, WFD_SINK_A_S_SINK, wfd_sink->ini.name_of_audio_sink, "audio_sink", TRUE);
+       MMWFDSINK_PAD_PROBE(wfd_sink, NULL, a_sinkbin[WFD_SINK_A_S_SINK].gst,  "sink");
+       if (a_sinkbin[WFD_SINK_A_S_SINK].gst) {
+               if (MM_ERROR_NONE != __mm_wfd_sink_prepare_audiosink(wfd_sink, a_sinkbin[WFD_SINK_A_S_SINK].gst)) {
+                       wfd_sink_error("failed to set audio sink property....");
+                       goto CREATE_ERROR;
+               }
+       }
+
+       /* adding created elements to audio sinkbin */
+       if (!__mm_wfd_sink_gst_element_add_bucket_to_bin(GST_BIN_CAST(a_sinkbin[WFD_SINK_A_S_BIN].gst), element_bucket, FALSE)) {
+               wfd_sink_error("failed to add elements to audio sinkbin");
+               goto CREATE_ERROR;
+       }
+
+       /* linking elements in the bucket by added order. */
+       if (__mm_wfd_sink_gst_element_link_bucket(element_bucket) == -1) {
+               wfd_sink_error("failed to link elements fo the audio sinkbin");
+               goto CREATE_ERROR;
+       }
+
+       /* get first element's of the audio sinkbin */
+       first_list = g_list_first(element_bucket);
+       if (first_list == NULL) {
+               wfd_sink_error("failed to get first list of the element_bucket");
+               goto CREATE_ERROR;
+       }
+
+       first_element = (MMWFDSinkGstElement *)first_list->data;
+       if (!first_element) {
+               wfd_sink_error("failed to get first element of the audio sinkbin");
+               goto CREATE_ERROR;
+       }
+
+       /* get first element's sinkpad for creating ghostpad */
+       pad = gst_element_get_static_pad(GST_ELEMENT(first_element->gst), "sink");
+       if (!pad) {
+               wfd_sink_error("failed to get sink pad from element(%s)",
+                       GST_STR_NULL(GST_ELEMENT_NAME(first_element->gst)));
+               goto CREATE_ERROR;
+       }
+
+       ghostpad = gst_ghost_pad_new("sink", pad);
+       if (!ghostpad) {
+               wfd_sink_error("failed to create ghostpad of audio sinkbin");
+               goto CREATE_ERROR;
+       }
+
+       if (FALSE == gst_element_add_pad(a_sinkbin[WFD_SINK_A_S_BIN].gst, ghostpad)) {
+               wfd_sink_error("failed to add ghostpad to audio sinkbin");
+               goto CREATE_ERROR;
+       }
+       gst_object_unref(GST_OBJECT(pad));
+
+       g_list_free(element_bucket);
+
+       /* take it */
+       wfd_sink->pipeline->a_sinkbin = a_sinkbin;
+
+       wfd_sink_debug_fleave();
+
+       return MM_ERROR_NONE;
+
+CREATE_ERROR:
+       wfd_sink_error("failed to create audio sinkbin, releasing all");
+
+       if (pad)
+               gst_object_unref(GST_OBJECT(pad));
+       pad = NULL;
+
+       if (ghostpad)
+               gst_object_unref(GST_OBJECT(ghostpad));
+       ghostpad = NULL;
+
+       if (element_bucket)
+               g_list_free(element_bucket);
+       element_bucket = NULL;
+
+       /* release element which are not added to bin */
+       for (i = 1; i < WFD_SINK_A_S_NUM; i++) {        /* NOTE : skip bin */
+               if (a_sinkbin != NULL && a_sinkbin[i].gst) {
+                       GstObject *parent = NULL;
+                       parent = gst_element_get_parent(a_sinkbin[i].gst);
+
+                       if (!parent) {
+                               gst_object_unref(GST_OBJECT(a_sinkbin[i].gst));
+                               a_sinkbin[i].gst = NULL;
+                       } else {
+                               gst_object_unref(GST_OBJECT(parent));
+                       }
+               }
+       }
+
+       /* release audio sinkbin with it's childs */
+       if (a_sinkbin != NULL && a_sinkbin[WFD_SINK_A_S_BIN].gst)
+               gst_object_unref(GST_OBJECT(a_sinkbin[WFD_SINK_A_S_BIN].gst));
+
+       MMWFDSINK_FREEIF(a_sinkbin);
+
+       return MM_ERROR_WFD_INTERNAL;
+}
+
+int __mm_wfd_sink_link_video_decodebin(mm_wfd_sink_t *wfd_sink)
+{
+       MMWFDSinkGstElement *v_decodebin = NULL;
+       MMWFDSinkGstElement *first_element = NULL;
+       MMWFDSinkGstElement *last_element = NULL;
+       GList *element_bucket = NULL;
+       GstPad *sinkpad = NULL;
+       GstPad *srcpad = NULL;
+       GstPad *ghostpad = NULL;
+       GList *first_list = NULL;
+       GList *last_list = NULL;
+
+       wfd_sink_debug_fenter();
+
+       wfd_sink_return_val_if_fail(wfd_sink &&
+                                               wfd_sink->pipeline &&
+                                               wfd_sink->pipeline->v_decodebin &&
+                                               wfd_sink->pipeline->v_decodebin[WFD_SINK_V_D_BIN].gst,
+                                               MM_ERROR_WFD_NOT_INITIALIZED);
+
+       if (wfd_sink->video_decodebin_is_linked) {
+               wfd_sink_debug("video decodebin is already linked... nothing to do");
+               return MM_ERROR_NONE;
+       }
+
+       /* take video decodebin */
+       v_decodebin = wfd_sink->pipeline->v_decodebin;
+
+       /* check video queue */
+       if (v_decodebin[WFD_SINK_V_D_QUEUE].gst)
+               element_bucket = g_list_append(element_bucket, &v_decodebin[WFD_SINK_V_D_QUEUE]);
+
+       /* check video hdcp */
+       if (v_decodebin[WFD_SINK_V_D_HDCP].gst)
+               element_bucket = g_list_append(element_bucket, &v_decodebin[WFD_SINK_V_D_HDCP]);
+
+       /* check video codec */
+       switch (wfd_sink->stream_info.video_stream_info.codec) {
+               case MM_WFD_SINK_VIDEO_CODEC_H264:
+                       if (v_decodebin[WFD_SINK_V_D_PARSE].gst)
+                               element_bucket = g_list_append(element_bucket, &v_decodebin[WFD_SINK_V_D_PARSE]);
+                       if (v_decodebin[WFD_SINK_V_D_CAPSSETTER].gst) {
+                               GstCaps *caps = NULL;
+
+                               element_bucket = g_list_append(element_bucket, &v_decodebin[WFD_SINK_V_D_CAPSSETTER]);
+                               caps = gst_caps_new_simple("video/x-h264",
+                                                                       "width", G_TYPE_INT, wfd_sink->stream_info.video_stream_info.width,
+                                                                       "height", G_TYPE_INT, wfd_sink->stream_info.video_stream_info.height,
+                                                                       "framerate", GST_TYPE_FRACTION, wfd_sink->stream_info.video_stream_info.frame_rate, 1, NULL);
+                               g_object_set(G_OBJECT(v_decodebin[WFD_SINK_V_D_CAPSSETTER].gst), "caps", caps, NULL);
+                               gst_object_unref(GST_OBJECT(caps));
+                       }
+                       if (v_decodebin[WFD_SINK_V_D_DEC].gst)
+                               element_bucket = g_list_append(element_bucket, &v_decodebin[WFD_SINK_V_D_DEC]);
+                       break;
+
+               default:
+                       wfd_sink_error("video codec is not decied yet. cannot link video decpdebin...");
+                       return MM_ERROR_WFD_INTERNAL;
+                       break;
+       }
+
+       if (element_bucket == NULL) {
+               wfd_sink_error("there are no elements to be linked in the video decodebin, destroy it");
+               if (MM_ERROR_NONE != __mm_wfd_sink_destroy_video_decodebin(wfd_sink)) {
+                       wfd_sink_error("failed to destroy video decodebin");
+                       goto fail_to_link;
+               }
+               goto done;
+       }
+
+       /* adding elements to video decodebin */
+       if (!__mm_wfd_sink_gst_element_add_bucket_to_bin(GST_BIN_CAST(v_decodebin[WFD_SINK_V_D_BIN].gst), element_bucket, FALSE)) {
+               wfd_sink_error("failed to add elements to video decodebin");
+               goto fail_to_link;
+       }
+
+       /* linking elements in the bucket by added order. */
+       if (__mm_wfd_sink_gst_element_link_bucket(element_bucket) == -1) {
+               wfd_sink_error("failed to link elements of the video decodebin");
+               goto fail_to_link;
+       }
+
+       /* get first element's sinkpad for creating ghostpad */
+       first_list = g_list_first(element_bucket);
+       if (first_list == NULL) {
+               wfd_sink_error("failed to get first list of the element_bucket");
+               goto fail_to_link;
+       }
+
+       first_element = (MMWFDSinkGstElement *)first_list->data;
+       if (!first_element) {
+               wfd_sink_error("failed to get first element of the video decodebin");
+               goto fail_to_link;
+       }
+
+       sinkpad = gst_element_get_static_pad(GST_ELEMENT(first_element->gst), "sink");
+       if (!sinkpad) {
+               wfd_sink_error("failed to get sink pad from element(%s)",
+                       GST_STR_NULL(GST_ELEMENT_NAME(first_element->gst)));
+               goto fail_to_link;
+       }
+
+       ghostpad = gst_ghost_pad_new("sink", sinkpad);
+       if (!ghostpad) {
+               wfd_sink_error("failed to create ghostpad of video decodebin");
+               goto fail_to_link;
+       }
+
+       if (FALSE == gst_element_add_pad(v_decodebin[WFD_SINK_V_D_BIN].gst, ghostpad)) {
+               wfd_sink_error("failed to add ghostpad to video decodebin");
+               goto fail_to_link;
+       }
+       gst_object_unref(GST_OBJECT(sinkpad));
+       sinkpad = NULL;
+
+
+       /* get last element's src for creating ghostpad */
+       last_list = g_list_last(element_bucket);
+       if (last_list == NULL) {
+               wfd_sink_error("failed to get last list of the element_bucket");
+               goto fail_to_link;
+       }
+
+       last_element = (MMWFDSinkGstElement *)last_list->data;
+       if (!last_element) {
+               wfd_sink_error("failed to get last element of the video decodebin");
+               goto fail_to_link;
+       }
+
+       srcpad = gst_element_get_static_pad(GST_ELEMENT(last_element->gst), "src");
+       if (!srcpad) {
+               wfd_sink_error("failed to get src pad from element(%s)",
+                       GST_STR_NULL(GST_ELEMENT_NAME(last_element->gst)));
+               goto fail_to_link;
+       }
+
+       ghostpad = gst_ghost_pad_new("src", srcpad);
+       if (!ghostpad) {
+               wfd_sink_error("failed to create ghostpad of video decodebin");
+               goto fail_to_link;
+       }
+
+       if (FALSE == gst_element_add_pad(v_decodebin[WFD_SINK_V_D_BIN].gst, ghostpad)) {
+               wfd_sink_error("failed to add ghostpad to video decodebin");
+               goto fail_to_link;
+       }
+       gst_object_unref(GST_OBJECT(srcpad));
+       srcpad = NULL;
+
+       g_list_free(element_bucket);
+
+done:
+       wfd_sink->video_decodebin_is_linked = TRUE;
+
+       wfd_sink_debug_fleave();
+
+       return MM_ERROR_NONE;
+
+       /* ERRORS*/
+fail_to_link:
+       if (srcpad != NULL)
+               gst_object_unref(GST_OBJECT(srcpad));
+       srcpad = NULL;
+
+       if (sinkpad != NULL)
+               gst_object_unref(GST_OBJECT(sinkpad));
+       sinkpad = NULL;
+
+       g_list_free(element_bucket);
+
+       return MM_ERROR_WFD_INTERNAL;
+}
+
+static int __mm_wfd_sink_prepare_videodec(mm_wfd_sink_t *wfd_sink, GstElement *video_dec)
+{
+       wfd_sink_debug_fenter();
+
+       /* check video decoder is created */
+       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);
+
+       wfd_sink_debug_fleave();
+
+       return MM_ERROR_NONE;
+}
+
+static int __mm_wfd_sink_prepare_videosink(mm_wfd_sink_t *wfd_sink, GstElement *video_sink)
+{
+       gboolean visible = TRUE;
+       gint surface_type = MM_DISPLAY_SURFACE_OVERLAY;
+
+       wfd_sink_debug_fenter();
+
+       /* check videosink is created */
+       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);
+       wfd_sink_debug("check display surface type attribute: %d", surface_type);
+       mm_attrs_get_int_by_name(wfd_sink->attrs, "display_visible", &visible);
+       wfd_sink_debug("check display visible attribute: %d", visible);
+
+       /* configuring display */
+       switch (surface_type) {
+               case MM_DISPLAY_SURFACE_EVAS: {
+                               void *object = NULL;
+                               gint scaling = 0;
+
+                               /* common case if using evas surface */
+                               mm_attrs_get_data_by_name(wfd_sink->attrs, "display_overlay", &object);
+                               mm_attrs_get_int_by_name(wfd_sink->attrs, "display_evas_do_scaling", &scaling);
+                               if (object) {
+                                       wfd_sink_debug("set video param : evas-object %x", object);
+                                       g_object_set(G_OBJECT(video_sink), "evas-object", object, NULL);
+                               } else {
+                                       wfd_sink_error("no evas object");
+                                       return MM_ERROR_WFD_INTERNAL;
+                               }
+                       }
+                       break;
+
+               case MM_DISPLAY_SURFACE_OVERLAY: {
+                               int wl_window_x = 0;
+                               int wl_window_y = 0;
+                               int wl_window_width = 0;
+                               int wl_window_height = 0;
+                               unsigned int wl_surface_id = 0;
+                               struct wl_surface *wl_surface = NULL;
+                               struct wl_display *wl_display = NULL;
+                               Ecore_Wl_Window *wl_window = NULL;
+                               wl_client *wlclient = NULL;
+                               Evas_Object *obj = NULL;
+                               void *object = NULL;
+                               const char *object_type = NULL;
+                               int ret = 0;
+
+                               mm_attrs_get_data_by_name(wfd_sink->attrs, "display_overlay", &object);
+
+                               if (object != NULL) {
+                                       obj = (Evas_Object *)object;
+                                       object_type = evas_object_type_get(obj);
+                                       wfd_sink_debug("window object type : %s", object_type);
+
+                                       /* wayland overlay surface */
+                                       LOGI("Wayland overlay surface type");
+                                       evas_object_geometry_get(obj, &wl_window_x, &wl_window_y, &wl_window_width, &wl_window_height);
+
+                                       wfd_sink_debug ("x[%d] y[%d] width[%d] height[%d]", wl_window_x, wl_window_y,
+                                               wl_window_width, wl_window_height);
+
+                                       wl_window = elm_win_wl_window_get(obj);
+                                       wl_surface = (struct wl_surface *) ecore_wl_window_surface_get(wl_window);
+
+                                       /* get wl_display */
+                                       wl_display = (struct wl_display *) ecore_wl_display_get();
+
+                                       ret = mm_wfd_sink_wlclient_create(&wlclient);
+                                       if ( ret != MM_ERROR_NONE) {
+                                               wfd_sink_error("Wayland client create failure");
+                                               return ret;
+                               }
+
+                                       if (wl_surface && wl_display){
+                                               wfd_sink_debug ("surface = %p, wl_display = %p", wl_surface, wl_display);
+                                               wl_surface_id = mm_wfd_sink_wlclient_get_wl_window_wl_surface_id (wlclient, wl_surface, wl_display);
+                                               wfd_sink_debug ("wl_surface_id = %d", wl_surface_id);
+                                       }
+                                       if (wlclient) {
+                                               g_free(wlclient);
+                                               wlclient = NULL;
+                                       }
+
+                                       wfd_sink_debug("set video param : surface_id %d", wl_surface_id);
+                                       gst_video_overlay_set_window_handle(GST_VIDEO_OVERLAY(video_sink),
+                                               wl_surface_id);
+                                       /* After setting window handle, set render rectangle */
+                                       gst_video_overlay_set_render_rectangle(GST_VIDEO_OVERLAY(video_sink),
+                                               wl_window_x, wl_window_y, wl_window_width, wl_window_height);
+                               } else {
+                                       wfd_sink_debug ("display object is NULL!");
+                                       return MM_ERROR_WFD_INTERNAL;
+                               }
+                       }
+                       break;
+
+               case MM_DISPLAY_SURFACE_NULL: {
+                               /* do nothing */
+                               wfd_sink_error("Not Supported Surface.");
+                               return MM_ERROR_WFD_INTERNAL;
+                       }
+                       break;
+               default: {
+                               wfd_sink_error("Not Supported Surface.(default case)");
+                               return MM_ERROR_WFD_INTERNAL;
+                       }
+                       break;
+       }
+
+       g_object_set(G_OBJECT(video_sink), "qos", 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);
+       g_object_set(G_OBJECT(video_sink), "ts-offset", (gint64)(wfd_sink->ini.sink_ts_offset), NULL);
+
+       wfd_sink_debug_fleave();
+
+       return MM_ERROR_NONE;
+}
+
+static int __mm_wfd_sink_destroy_video_decodebin(mm_wfd_sink_t *wfd_sink)
+{
+       GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
+       MMWFDSinkGstElement *v_decodebin = 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->v_decodebin &&
+           wfd_sink->pipeline->v_decodebin[WFD_SINK_V_D_BIN].gst) {
+               v_decodebin = wfd_sink->pipeline->v_decodebin;
+       } else {
+               wfd_sink_debug("video decodebin is not created, nothing to destroy");
+               return MM_ERROR_NONE;
+       }
+
+
+       parent = gst_element_get_parent(v_decodebin[WFD_SINK_V_D_BIN].gst);
+       if (!parent) {
+               wfd_sink_debug("video decodebin has no parent.. need to relase by itself");
+
+               if (GST_STATE(v_decodebin[WFD_SINK_V_D_BIN].gst) >= GST_STATE_READY) {
+                       wfd_sink_debug("try to change state of video decodebin to NULL");
+                       ret = gst_element_set_state(v_decodebin[WFD_SINK_V_D_BIN].gst, GST_STATE_NULL);
+                       if (ret != GST_STATE_CHANGE_SUCCESS) {
+                               wfd_sink_error("failed to change state of video decodebin to NULL");
+                               return MM_ERROR_WFD_INTERNAL;
+                       }
+               }
+               /* release element which are not added to bin */
+               for (i = 1; i < WFD_SINK_V_D_NUM; i++) {        /* NOTE : skip bin */
+                       if (v_decodebin[i].gst) {
+                               parent = gst_element_get_parent(v_decodebin[i].gst);
+                               if (!parent) {
+                                       wfd_sink_debug("unref %s(current ref %d)",
+                                                               GST_STR_NULL(GST_ELEMENT_NAME(v_decodebin[i].gst)),
+                                                               ((GObject *) v_decodebin[i].gst)->ref_count);
+                                       gst_object_unref(GST_OBJECT(v_decodebin[i].gst));
+                                       v_decodebin[i].gst = NULL;
+                               } else {
+                                       wfd_sink_debug("unref %s(current ref %d)",
+                                                               GST_STR_NULL(GST_ELEMENT_NAME(v_decodebin[i].gst)),
+                                                               ((GObject *) v_decodebin[i].gst)->ref_count);
+                                       gst_object_unref(GST_OBJECT(parent));
+                               }
+                       }
+               }
+               /* release video decodebin with it's childs */
+               if (v_decodebin[WFD_SINK_V_D_BIN].gst) {
+                       gst_object_unref(GST_OBJECT(v_decodebin[WFD_SINK_V_D_BIN].gst));
+                       wfd_sink_debug("unref %s(current ref %d)",
+                                               GST_STR_NULL(GST_ELEMENT_NAME(v_decodebin[WFD_SINK_V_D_BIN].gst)),
+                                               ((GObject *)v_decodebin[WFD_SINK_V_D_BIN].gst)->ref_count);
+               }
+       } else {
+               wfd_sink_debug("video decodebin has parent(%s), unref it",
+                                       GST_STR_NULL(GST_OBJECT_NAME(GST_OBJECT(parent))));
+
+               gst_object_unref(GST_OBJECT(parent));
+       }
+
+       wfd_sink->video_decodebin_is_linked = FALSE;
+
+       MMWFDSINK_FREEIF(wfd_sink->pipeline->v_decodebin);
+
+       wfd_sink_debug_fleave();
+
+       return MM_ERROR_NONE;
+}
+
+static int __mm_wfd_sink_create_video_decodebin(mm_wfd_sink_t *wfd_sink)
+{
+       MMWFDSinkGstElement *v_decodebin = NULL;
+       guint video_codec = WFD_VIDEO_UNKNOWN;
+       GList *element_bucket = NULL;
+       gboolean link = TRUE;
+       gint i = 0;
+
+       wfd_sink_debug_fenter();
+
+       wfd_sink_return_val_if_fail(wfd_sink &&
+                                               wfd_sink->pipeline,
+                                               MM_ERROR_WFD_NOT_INITIALIZED);
+
+       if (wfd_sink->pipeline->v_decodebin) {
+               wfd_sink_debug("video decodebin is already created... nothing to do");
+               return MM_ERROR_NONE;
+       }
+
+       /* check audio decodebin could be linked now */
+       switch (wfd_sink->stream_info.video_stream_info.codec) {
+               case MM_WFD_SINK_VIDEO_CODEC_H264:
+                       video_codec = WFD_VIDEO_H264;
+                       link = TRUE;
+                       break;
+               case MM_WFD_SINK_VIDEO_CODEC_NONE:
+               default:
+                       wfd_sink_debug("video decodebin could NOT be linked now, just create");
+                       video_codec = wfd_sink->ini.video_codec;
+                       link = FALSE;
+                       break;
+       }
+
+       /* alloc handles */
+       v_decodebin = (MMWFDSinkGstElement *)g_malloc0(sizeof(MMWFDSinkGstElement) * WFD_SINK_V_D_NUM);
+       if (!v_decodebin) {
+               wfd_sink_error("failed to allocate memory for video decodebin");
+               return MM_ERROR_WFD_NO_FREE_SPACE;
+       }
+
+       memset(v_decodebin, 0, sizeof(MMWFDSinkGstElement) * WFD_SINK_V_D_NUM);
+
+       /* create video decodebin */
+       v_decodebin[WFD_SINK_V_D_BIN].id = WFD_SINK_V_D_BIN;
+       v_decodebin[WFD_SINK_V_D_BIN].gst = gst_bin_new("video_decodebin");
+       if (!v_decodebin[WFD_SINK_V_D_BIN].gst) {
+               wfd_sink_error("failed to create video decodebin");
+               goto CREATE_ERROR;
+       }
+
+       /* create queue */
+       MMWFDSINK_CREATE_ELEMENT(v_decodebin, WFD_SINK_V_D_QUEUE, "queue", "video_queue", FALSE);
+       MMWFDSINK_PAD_PROBE(wfd_sink, NULL, v_decodebin[WFD_SINK_V_D_QUEUE].gst,  "sink");
+       if (v_decodebin[WFD_SINK_V_D_QUEUE].gst)
+               __mm_wfd_sink_prepare_queue(wfd_sink, v_decodebin[WFD_SINK_V_D_QUEUE].gst);
+
+       /* create hdcp */
+       MMWFDSINK_CREATE_ELEMENT(v_decodebin, WFD_SINK_V_D_HDCP, wfd_sink->ini.name_of_video_hdcp, "video_hdcp", FALSE);
+       MMWFDSINK_PAD_PROBE(wfd_sink, NULL, v_decodebin[WFD_SINK_V_D_HDCP].gst,  "sink");
+       MMWFDSINK_PAD_PROBE(wfd_sink, NULL, v_decodebin[WFD_SINK_V_D_HDCP].gst,  "src");
+
+       if (video_codec & WFD_VIDEO_H264) {
+               /* create parser */
+               MMWFDSINK_CREATE_ELEMENT(v_decodebin, WFD_SINK_V_D_PARSE, wfd_sink->ini.name_of_video_parser, "video_parser", FALSE);
+               MMWFDSINK_PAD_PROBE(wfd_sink, NULL, v_decodebin[WFD_SINK_V_D_PARSE].gst,  "sink");
+               MMWFDSINK_PAD_PROBE(wfd_sink, NULL, v_decodebin[WFD_SINK_V_D_PARSE].gst,  "src");
+
+               /* create capssetter */
+               MMWFDSINK_CREATE_ELEMENT(v_decodebin, WFD_SINK_V_D_CAPSSETTER, wfd_sink->ini.name_of_video_capssetter, "video_capssetter", FALSE);
+               MMWFDSINK_PAD_PROBE(wfd_sink, NULL, v_decodebin[WFD_SINK_V_D_CAPSSETTER].gst,  "sink");
+               MMWFDSINK_PAD_PROBE(wfd_sink, NULL, v_decodebin[WFD_SINK_V_D_CAPSSETTER].gst,  "src");
+
+               /* create dec */
+               MMWFDSINK_CREATE_ELEMENT(v_decodebin, WFD_SINK_V_D_DEC, wfd_sink->ini.name_of_video_decoder, "video_dec", FALSE);
+               MMWFDSINK_PAD_PROBE(wfd_sink, NULL, v_decodebin[WFD_SINK_V_D_DEC].gst,  "sink");
+               MMWFDSINK_PAD_PROBE(wfd_sink, NULL, v_decodebin[WFD_SINK_V_D_DEC].gst,  "src");
+               if (v_decodebin[WFD_SINK_V_D_DEC].gst) {
+                       if (MM_ERROR_NONE != __mm_wfd_sink_prepare_videodec(wfd_sink, v_decodebin[WFD_SINK_V_D_DEC].gst)) {
+                               wfd_sink_error("failed to set video decoder property...");
+                               goto CREATE_ERROR;
+                       }
+               }
+       }
+
+       g_list_free(element_bucket);
+
+       /* take it */
+       wfd_sink->pipeline->v_decodebin = v_decodebin;
+
+       /* link video decodebin if video codec is fixed */
+       if (link) {
+               if (MM_ERROR_NONE != __mm_wfd_sink_link_video_decodebin(wfd_sink)) {
+                       wfd_sink_error("failed to link video decodebin, destroy video decodebin");
+                       __mm_wfd_sink_destroy_video_decodebin(wfd_sink);
+                       return MM_ERROR_WFD_INTERNAL;
+               }
+       }
+
+       wfd_sink_debug_fleave();
+
+       return MM_ERROR_NONE;
+
+       /* ERRORS */
+CREATE_ERROR:
+       wfd_sink_error("failed to create video decodebin, releasing all");
+
+       g_list_free(element_bucket);
+
+       /* release element which are not added to bin */
+       for (i = 1; i < WFD_SINK_V_D_NUM; i++) {        /* NOTE : skip bin */
+               if (v_decodebin != NULL && v_decodebin[i].gst) {
+                       GstObject *parent = NULL;
+                       parent = gst_element_get_parent(v_decodebin[i].gst);
+
+                       if (!parent) {
+                               gst_object_unref(GST_OBJECT(v_decodebin[i].gst));
+                               v_decodebin[i].gst = NULL;
+                       } else {
+                               gst_object_unref(GST_OBJECT(parent));
+                       }
+               }
+       }
+
+       /* release video decodebin with it's childs */
+       if (v_decodebin != NULL && v_decodebin[WFD_SINK_V_D_BIN].gst)
+               gst_object_unref(GST_OBJECT(v_decodebin[WFD_SINK_V_D_BIN].gst));
+
+       MMWFDSINK_FREEIF(v_decodebin);
+
+       return MM_ERROR_WFD_INTERNAL;
+}
+
+static int __mm_wfd_sink_destroy_video_sinkbin(mm_wfd_sink_t *wfd_sink)
+{
+       GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
+       MMWFDSinkGstElement *v_sinkbin = 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->v_sinkbin &&
+           wfd_sink->pipeline->v_sinkbin[WFD_SINK_V_S_BIN].gst) {
+               v_sinkbin = wfd_sink->pipeline->v_sinkbin;
+       } else {
+               wfd_sink_debug("video sinkbin is not created, nothing to destroy");
+               return MM_ERROR_NONE;
+       }
+
+
+       parent = gst_element_get_parent(v_sinkbin[WFD_SINK_V_S_BIN].gst);
+       if (!parent) {
+               wfd_sink_debug("video sinkbin has no parent.. need to relase by itself");
+
+               if (GST_STATE(v_sinkbin[WFD_SINK_V_S_BIN].gst) >= GST_STATE_READY) {
+                       wfd_sink_debug("try to change state of video sinkbin to NULL");
+                       ret = gst_element_set_state(v_sinkbin[WFD_SINK_V_S_BIN].gst, GST_STATE_NULL);
+                       if (ret != GST_STATE_CHANGE_SUCCESS) {
+                               wfd_sink_error("failed to change state of video sinkbin to NULL");
+                               return MM_ERROR_WFD_INTERNAL;
+                       }
+               }
+               /* release element which are not added to bin */
+               for (i = 1; i < WFD_SINK_V_S_NUM; i++) {        /* NOTE : skip bin */
+                       if (v_sinkbin[i].gst) {
+                               parent = gst_element_get_parent(v_sinkbin[i].gst);
+                               if (!parent) {
+                                       wfd_sink_debug("unref %s(current ref %d)",
+                                                               GST_STR_NULL(GST_ELEMENT_NAME(v_sinkbin[i].gst)),
+                                                               ((GObject *) v_sinkbin[i].gst)->ref_count);
+                                       gst_object_unref(GST_OBJECT(v_sinkbin[i].gst));
+                                       v_sinkbin[i].gst = NULL;
+                               } else {
+                                       wfd_sink_debug("unref %s(current ref %d)",
+                                                               GST_STR_NULL(GST_ELEMENT_NAME(v_sinkbin[i].gst)),
+                                                               ((GObject *) v_sinkbin[i].gst)->ref_count);
+                                       gst_object_unref(GST_OBJECT(parent));
+                               }
+                       }
+               }
+               /* release video sinkbin with it's childs */
+               if (v_sinkbin[WFD_SINK_V_S_BIN].gst) {
+                       gst_object_unref(GST_OBJECT(v_sinkbin[WFD_SINK_V_S_BIN].gst));
+               }
+       } else {
+               wfd_sink_debug("video sinkbin has parent(%s), unref it ",
+                                       GST_STR_NULL(GST_OBJECT_NAME(GST_OBJECT(parent))));
+
+               gst_object_unref(GST_OBJECT(parent));
+       }
+
+       MMWFDSINK_FREEIF(wfd_sink->pipeline->v_sinkbin);
+
+       wfd_sink_debug_fleave();
+
+       return MM_ERROR_NONE;
+}
+
+static int __mm_wfd_sink_create_video_sinkbin(mm_wfd_sink_t *wfd_sink)
+{
+       MMWFDSinkGstElement *first_element = NULL;
+       MMWFDSinkGstElement *v_sinkbin = NULL;
+       GList *element_bucket = NULL;
+       GstPad *pad = NULL;
+       GstPad *ghostpad = NULL;
+       gint i = 0;
+       gint surface_type = MM_DISPLAY_SURFACE_OVERLAY;
+
+       wfd_sink_debug_fenter();
+
+       wfd_sink_return_val_if_fail(wfd_sink &&
+                                               wfd_sink->pipeline,
+                                               MM_ERROR_WFD_NOT_INITIALIZED);
+
+       /* alloc handles */
+       v_sinkbin = (MMWFDSinkGstElement *)g_malloc0(sizeof(MMWFDSinkGstElement) * WFD_SINK_V_S_NUM);
+       if (!v_sinkbin) {
+               wfd_sink_error("failed to allocate memory for video sinkbin");
+               return MM_ERROR_WFD_NO_FREE_SPACE;
+       }
+
+       memset(v_sinkbin, 0, sizeof(MMWFDSinkGstElement) * WFD_SINK_V_S_NUM);
+
+       /* create video sinkbin */
+       v_sinkbin[WFD_SINK_V_S_BIN].id = WFD_SINK_V_S_BIN;
+       v_sinkbin[WFD_SINK_V_S_BIN].gst = gst_bin_new("video_sinkbin");
+       if (!v_sinkbin[WFD_SINK_V_S_BIN].gst) {
+               wfd_sink_error("failed to create video sinkbin");
+               goto CREATE_ERROR;
+       }
+
+       /* create convert */
+       MMWFDSINK_CREATE_ELEMENT(v_sinkbin, WFD_SINK_V_S_CONVERT, wfd_sink->ini.name_of_video_converter, "video_convert", TRUE);
+       MMWFDSINK_PAD_PROBE(wfd_sink, NULL, v_sinkbin[WFD_SINK_V_S_CONVERT].gst,  "sink");
+       MMWFDSINK_PAD_PROBE(wfd_sink, NULL, v_sinkbin[WFD_SINK_V_S_CONVERT].gst,  "src");
+
+       /* create filter */
+       MMWFDSINK_CREATE_ELEMENT(v_sinkbin, WFD_SINK_V_S_FILTER, wfd_sink->ini.name_of_video_filter, "video_filter", TRUE);
+       MMWFDSINK_PAD_PROBE(wfd_sink, NULL, v_sinkbin[WFD_SINK_V_S_FILTER].gst,  "sink");
+       MMWFDSINK_PAD_PROBE(wfd_sink, NULL, v_sinkbin[WFD_SINK_V_S_FILTER].gst,  "src");
+       if (v_sinkbin[WFD_SINK_V_S_FILTER].gst) {
+               GstCaps *caps = NULL;
+               caps = gst_caps_new_simple("video/x-raw", "format", G_TYPE_STRING, "SN12", NULL);
+               g_object_set(G_OBJECT(v_sinkbin[WFD_SINK_V_S_FILTER].gst), "caps", caps, NULL);
+               gst_object_unref(GST_OBJECT(caps));
+       }
+
+       /* create sink */
+       mm_attrs_get_int_by_name(wfd_sink->attrs, "display_surface_type", &surface_type);
+
+       if (surface_type == MM_DISPLAY_SURFACE_OVERLAY) {
+               MMWFDSINK_CREATE_ELEMENT(v_sinkbin, WFD_SINK_V_S_SINK, wfd_sink->ini.name_of_video_sink, "video_sink", TRUE);
+       } else if (surface_type == MM_DISPLAY_SURFACE_EVAS) {
+               MMWFDSINK_CREATE_ELEMENT(v_sinkbin, WFD_SINK_V_S_SINK, wfd_sink->ini.name_of_video_evas_sink, "video_sink", TRUE);
+       } else {
+               wfd_sink_error("failed to set video sink....");
+               goto CREATE_ERROR;
+       }
+
+       MMWFDSINK_PAD_PROBE(wfd_sink, NULL, v_sinkbin[WFD_SINK_V_S_SINK].gst,  "sink");
+       if (v_sinkbin[WFD_SINK_V_S_SINK].gst) {
+               if (MM_ERROR_NONE != __mm_wfd_sink_prepare_videosink(wfd_sink, v_sinkbin[WFD_SINK_V_S_SINK].gst)) {
+                       wfd_sink_error("failed to set video sink property....");
+                       goto CREATE_ERROR;
+               }
+       }
+
+       /* adding created elements to video sinkbin */
+       if (!__mm_wfd_sink_gst_element_add_bucket_to_bin(GST_BIN_CAST(v_sinkbin[WFD_SINK_V_S_BIN].gst), element_bucket, FALSE)) {
+               wfd_sink_error("failed to add elements to video sinkbin");
+               goto CREATE_ERROR;
+       }
+
+       /* linking elements in the bucket by added order. */
+       if (__mm_wfd_sink_gst_element_link_bucket(element_bucket) == -1) {
+               wfd_sink_error("failed to link elements of the video sinkbin");
+               goto CREATE_ERROR;
+       }
+
+       /* get first element's sinkpad for creating ghostpad */
+       first_element = (MMWFDSinkGstElement *)g_list_nth_data(element_bucket, 0);
+       if (!first_element) {
+               wfd_sink_error("failed to get first element of the video sinkbin");
+               goto CREATE_ERROR;
+       }
+
+       pad = gst_element_get_static_pad(GST_ELEMENT(first_element->gst), "sink");
+       if (!pad) {
+               wfd_sink_error("failed to get pad from first element(%s) of the video sinkbin",
+                       GST_STR_NULL(GST_ELEMENT_NAME(first_element->gst)));
+               goto CREATE_ERROR;
+       }
+
+       ghostpad = gst_ghost_pad_new("sink", pad);
+       if (!ghostpad) {
+               wfd_sink_error("failed to create ghostpad of the video sinkbin");
+               goto CREATE_ERROR;
+       }
+
+       if (FALSE == gst_element_add_pad(v_sinkbin[WFD_SINK_V_S_BIN].gst, ghostpad)) {
+               wfd_sink_error("failed to add ghostpad to video sinkbin");
+               goto CREATE_ERROR;
+       }
+
+       gst_object_unref(GST_OBJECT(pad));
+
+       g_list_free(element_bucket);
+
+
+       /* take it */
+       wfd_sink->pipeline->v_sinkbin = v_sinkbin;
+
+       wfd_sink_debug_fleave();
+
+       return MM_ERROR_NONE;
+
+       /* ERRORS */
+CREATE_ERROR:
+       wfd_sink_error("failed to create video sinkbin, releasing all");
+
+       if (pad)
+               gst_object_unref(GST_OBJECT(pad));
+       pad = NULL;
+
+       if (ghostpad)
+               gst_object_unref(GST_OBJECT(ghostpad));
+       ghostpad = NULL;
+
+       g_list_free(element_bucket);
+
+       /* release element which are not added to bin */
+       for (i = 1; i < WFD_SINK_V_S_NUM; i++) {        /* NOTE : skip bin */
+               if (v_sinkbin != NULL && v_sinkbin[i].gst) {
+                       GstObject *parent = NULL;
+                       parent = gst_element_get_parent(v_sinkbin[i].gst);
+
+                       if (!parent) {
+                               gst_object_unref(GST_OBJECT(v_sinkbin[i].gst));
+                               v_sinkbin[i].gst = NULL;
+                       } else {
+                               gst_object_unref(GST_OBJECT(parent));
+                       }
+               }
+       }
+
+       /* release video sinkbin with it's childs */
+       if (v_sinkbin != NULL && v_sinkbin[WFD_SINK_V_S_BIN].gst)
+               gst_object_unref(GST_OBJECT(v_sinkbin[WFD_SINK_V_S_BIN].gst));
+
+       MMWFDSINK_FREEIF(v_sinkbin);
+
+       return MM_ERROR_WFD_INTERNAL;
+}
+
+static int __mm_wfd_sink_destroy_pipeline(mm_wfd_sink_t *wfd_sink)
+{
+       GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
+
+       wfd_sink_debug_fenter();
+
+       wfd_sink_return_val_if_fail(wfd_sink, MM_ERROR_WFD_NOT_INITIALIZED);
+
+       /* cleanup gst stuffs */
+       if (wfd_sink->pipeline) {
+               MMWFDSinkGstElement *mainbin = wfd_sink->pipeline->mainbin;
+
+               if (mainbin) {
+                       ret = gst_element_set_state(mainbin[WFD_SINK_M_PIPE].gst, GST_STATE_NULL);
+                       if (ret != GST_STATE_CHANGE_SUCCESS) {
+                               wfd_sink_error("failed to change state of mainbin to NULL");
+                               return MM_ERROR_WFD_INTERNAL;
+                       }
+
+                       if (MM_ERROR_NONE != __mm_wfd_sink_destroy_video_decodebin(wfd_sink)) {
+                               wfd_sink_error("failed to destroy video decodebin");
+                               return MM_ERROR_WFD_INTERNAL;
+                       }
+
+                       if (MM_ERROR_NONE != __mm_wfd_sink_destroy_audio_decodebin(wfd_sink)) {
+                               wfd_sink_error("failed to destroy audio decodebin");
+                               return MM_ERROR_WFD_INTERNAL;
+                       }
+
+                       if (MM_ERROR_NONE != __mm_wfd_sink_destroy_video_sinkbin(wfd_sink)) {
+                               wfd_sink_error("failed to destroy video sinkbin");
+                               return MM_ERROR_WFD_INTERNAL;
+                       }
+
+                       if (MM_ERROR_NONE != __mm_wfd_sink_destroy_audio_sinkbin(wfd_sink)) {
+                               wfd_sink_error("failed to destroy audio sinkbin");
+                               return MM_ERROR_WFD_INTERNAL;
+                       }
+
+                       gst_object_unref(GST_OBJECT(mainbin[WFD_SINK_M_PIPE].gst));
+
+                       MMWFDSINK_FREEIF(mainbin);
+               }
+
+               MMWFDSINK_FREEIF(wfd_sink->pipeline);
+       }
+
+       wfd_sink->audio_decodebin_is_linked = FALSE;
+       wfd_sink->video_decodebin_is_linked = FALSE;
+       wfd_sink->need_to_reset_basetime = FALSE;
+
+       wfd_sink_debug_fleave();
+
+       return MM_ERROR_NONE;
+}
+
+static void
+__mm_wfd_sink_dump_pipeline_state(mm_wfd_sink_t *wfd_sink)
+{
+       GstIterator *iter = NULL;
+       gboolean done = FALSE;
+
+       GstElement *item = NULL;
+       GstElementFactory *factory = NULL;
+
+       GstState state = GST_STATE_VOID_PENDING;
+       GstState pending = GST_STATE_VOID_PENDING;
+       GstClockTime time = 200 * GST_MSECOND;
+
+       wfd_sink_debug_fenter();
+
+       wfd_sink_return_if_fail(wfd_sink &&
+                                               wfd_sink->pipeline &&
+                                               wfd_sink->pipeline->mainbin &&
+                                               wfd_sink->pipeline->mainbin[WFD_SINK_M_PIPE].gst);
+
+       iter = gst_bin_iterate_recurse(GST_BIN(wfd_sink->pipeline->mainbin[WFD_SINK_M_PIPE].gst));
+
+       if (iter != NULL) {
+               while (!done) {
+                       switch (gst_iterator_next(iter, (gpointer)&item)) {
+                               case GST_ITERATOR_OK:
+                                       gst_element_get_state(GST_ELEMENT(item), &state, &pending, time);
+
+                                       factory = gst_element_get_factory(item) ;
+                                       if (factory) {
+                                               wfd_sink_error("%s:%s : From:%s To:%s refcount : %d",
+                                                                       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;
+                               case GST_ITERATOR_RESYNC:
+                                       gst_iterator_resync(iter);
+                                       break;
+                               case GST_ITERATOR_ERROR:
+                                       done = TRUE;
+                                       break;
+                               case GST_ITERATOR_DONE:
+                                       done = TRUE;
+                                       break;
+                               default:
+                                       done = TRUE;
+                                       break;
+                       }
+               }
+       }
+
+       item = GST_ELEMENT_CAST(wfd_sink->pipeline->mainbin[WFD_SINK_M_PIPE].gst);
+
+       gst_element_get_state(GST_ELEMENT(item), &state, &pending, time);
+
+       factory = gst_element_get_factory(item) ;
+       if (factory) {
+               wfd_sink_error("%s:%s : From:%s To:%s refcount : %d",
+                                       GST_OBJECT_NAME(factory),
+                                       GST_ELEMENT_NAME(item),
+                                       gst_element_state_get_name(state),
+                                       gst_element_state_get_name(pending),
+                                       GST_OBJECT_REFCOUNT_VALUE(item));
+       }
+
+       if (iter)
+               gst_iterator_free(iter);
+
+       wfd_sink_debug_fleave();
+
+       return;
+}
+
+const gchar * _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_PREPARED:
+                       return "PREPARED";
+               case MM_WFD_SINK_STATE_CONNECTED:
+                       return "CONNECTED";
+               case MM_WFD_SINK_STATE_PLAYING:
+                       return "PLAYING";
+               case MM_WFD_SINK_STATE_PAUSED:
+                       return "PAUSED";
+               case MM_WFD_SINK_STATE_DISCONNECTED:
+                       return "DISCONNECTED";
+               default:
+                       return "INVAID";
+       }
+}
+
+static void __mm_wfd_sink_prepare_video_resolution(gint resolution, guint *CEA_resolution, guint *VESA_resolution, guint *HH_resolution)
+{
+       if (resolution == MM_WFD_SINK_RESOLUTION_UNKNOWN) return;
+
+       *CEA_resolution = 0;
+       *VESA_resolution = 0;
+       *HH_resolution = 0;
+
+       if (resolution & MM_WFD_SINK_RESOLUTION_1920x1080_P30)
+               *CEA_resolution |= WFD_CEA_1920x1080P30;
+
+       if (resolution & MM_WFD_SINK_RESOLUTION_1280x720_P30)
+               *CEA_resolution |= WFD_CEA_1280x720P30;
+
+       if (resolution & MM_WFD_SINK_RESOLUTION_960x540_P30)
+               *HH_resolution |= WFD_HH_960x540P30;
+
+       if (resolution & MM_WFD_SINK_RESOLUTION_864x480_P30)
+               *HH_resolution |= WFD_HH_864x480P30;
+
+       if (resolution & MM_WFD_SINK_RESOLUTION_720x480_P60)
+               *CEA_resolution |= WFD_CEA_720x480P60;
+
+       if (resolution & MM_WFD_SINK_RESOLUTION_640x480_P60)
+               *CEA_resolution |= WFD_CEA_640x480P60;
+
+       if (resolution & MM_WFD_SINK_RESOLUTION_640x360_P30)
+               *HH_resolution |= WFD_HH_640x360P30;
+}
+
+int _mm_wfd_sink_set_resolution(mm_wfd_sink_t *wfd_sink, MMWFDSinkResolution resolution)
+{
+       MMWFDSinkStateType cur_state = MM_WFD_SINK_STATE_NONE;
+
+       wfd_sink_debug_fenter();
+
+       wfd_sink_return_val_if_fail(wfd_sink, MM_ERROR_WFD_NOT_INITIALIZED);
+
+       MMWFDSINK_PRINT_STATE(wfd_sink);
+       cur_state = MMWFDSINK_CURRENT_STATE(wfd_sink);
+       if (cur_state != MM_WFD_SINK_STATE_NULL) {
+               wfd_sink_error("This function must be called when MM_WFD_SINK_STATE_NULL");
+               return MM_ERROR_WFD_INVALID_STATE;
+       }
+
+       wfd_sink->supportive_resolution = resolution;
+
+       wfd_sink_debug_fleave();
+
+       return MM_ERROR_NONE;
+}
diff --git a/src/mm_wfd_sink_util.c b/src/mm_wfd_sink_util.c
new file mode 100755 (executable)
index 0000000..405a818
--- /dev/null
@@ -0,0 +1,224 @@
+/*
+ * libmm-wfd
+ *
+ * Copyright (c) 2011 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: JongHyuk Choi <jhchoi.choi@samsung.com>, ByungWook Jang <bw.jang@samsung.com>,
+ * Maksym Ukhanov <m.ukhanov@samsung.com>, Hyunjun Ko <zzoon.ko@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include "mm_wfd_sink_util.h"
+#include <stdio.h>
+#include <tzplatform_config.h>
+
+#define DUMP_TS_DATA_PATH tzplatform_mkpath(TZ_SYS_VAR, "tmp/")
+
+static GstPadProbeReturn
+_mm_wfd_sink_util_dump(GstPad *pad, GstPadProbeInfo *info, gpointer u_data)
+{
+       gint8 *data = NULL;
+       gint size = 0;
+       FILE *f = NULL;
+       char buf[256] = {0, };
+       char path[256] = {0, };
+       GstElement * parent = NULL;
+
+       parent = gst_pad_get_parent_element(pad);
+       if (parent == NULL) {
+               wfd_sink_error("The parent of pad is NULL.");
+               return GST_PAD_PROBE_OK;
+       }
+
+       snprintf(path, sizeof(path), "%s%s_%s.ts", DUMP_TS_DATA_PATH, gst_element_get_name(parent), gst_pad_get_name(pad));
+       gst_object_unref(parent);
+
+       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);
+
+               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));
+                       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 GST_PAD_PROBE_OK;
+}
+
+static GstPadProbeReturn
+_mm_wfd_sink_util_pad_probe_cb(GstPad *pad, GstPadProbeInfo *info, gpointer u_data)
+{
+       GstElement *parent = NULL;
+
+       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);
+
+       parent = (GstElement *)gst_object_get_parent(GST_OBJECT(pad));
+       if (!parent) {
+               wfd_sink_error("failed to get parent of pad");
+               return GST_PAD_PROBE_DROP;
+       }
+
+       if (info->type & GST_PAD_PROBE_TYPE_BUFFER) {
+               GstBuffer *buffer = gst_pad_probe_info_get_buffer(info);
+               /* show name and timestamp */
+               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 */
+               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) {
+                       const GstSegment *segment = NULL;
+                       gst_event_parse_segment(event, &segment);
+                       if (segment)
+                               wfd_sink_debug("NEWSEGMENT : %" GST_TIME_FORMAT
+                                                       " -- %"  GST_TIME_FORMAT ", time %" GST_TIME_FORMAT " \n",
+                                                       GST_TIME_ARGS(segment->start), GST_TIME_ARGS(segment->stop),
+                                                       GST_TIME_ARGS(segment->time));
+               }
+       }
+
+       if (parent)
+               gst_object_unref(parent);
+
+       return GST_PAD_PROBE_OK;
+}
+
+void
+mm_wfd_sink_util_add_pad_probe(GstPad *pad, GstElement *element, const gchar *pad_name)
+{
+       GstPad *probe_pad = 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) {
+               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);
+       }
+}
+
+void
+mm_wfd_sink_util_add_pad_probe_for_data_dump(GstElement *element, const gchar *pad_name)
+{
+       GstPad *probe_pad = NULL;
+
+       if (element && pad_name)
+               probe_pad = gst_element_get_static_pad(element, pad_name);
+
+       if (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;
+}
+
diff --git a/src/mm_wfd_sink_wayland.c b/src/mm_wfd_sink_wayland.c
new file mode 100755 (executable)
index 0000000..787dea8
--- /dev/null
@@ -0,0 +1,148 @@
+/*
+* 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.
+*/
+
+#include <glib.h>
+#include <string.h>
+#include <mm_error.h>
+#include <wayland-client.h>
+#include <tizen-extension-client-protocol.h>
+
+#include "mm_wfd_sink_dlog.h"
+#include "mm_wfd_sink_wayland.h"
+
+#define goto_if_fail(expr,label)       \
+{      \
+       if (!(expr)) {  \
+               wfd_sink_error(" failed [%s]\n", #expr);        \
+               goto label;     \
+       }       \
+}
+
+void mm_wfd_sink_handle_resource_id(void *data, struct tizen_resource *tizen_resource, uint32_t id)
+{
+       unsigned int *wl_surface_id = data;
+
+       *wl_surface_id = id;
+
+       wfd_sink_debug("[CLIENT] got wl_surface_id(%d) from server\n", id);
+}
+
+static const struct tizen_resource_listener tz_resource_listener =
+{
+       mm_wfd_sink_handle_resource_id,
+};
+
+static void
+mm_wfd_sink_handle_global(void *data, struct wl_registry *registry,
+              uint32_t name, const char *interface, uint32_t version)
+{
+       return_if_fail (data != NULL);
+       wl_client *wlclient = data;
+
+       if (strcmp(interface, "tizen_surface") == 0)
+       {
+               wfd_sink_debug("binding tizen_surface");
+               wlclient->tz_surface = wl_registry_bind(registry, name, &tizen_surface_interface, version);
+               return_if_fail (wlclient->tz_surface != NULL);
+       }
+}
+
+static void mm_wfd_sink_handle_global_remove(void* data, struct wl_registry* registry, uint32_t name)
+{
+       wfd_sink_debug("wl_registry_handle_global_remove");
+}
+
+static const struct wl_registry_listener registry_listener =
+{
+       mm_wfd_sink_handle_global,
+       mm_wfd_sink_handle_global_remove
+};
+
+int mm_wfd_sink_wlclient_create (wl_client ** wlclient)
+{
+       wl_client *ptr = NULL;
+
+       ptr = g_malloc0 (sizeof (wl_client));
+       if (!ptr) {
+               wfd_sink_error ("Cannot allocate memory for wlclient\n");
+               goto ERROR;
+       } else {
+               *wlclient = ptr;
+               wfd_sink_debug ("Success create wlclient(%p)", *wlclient);
+       }
+       return MM_ERROR_NONE;
+
+ERROR:
+       *wlclient = NULL;
+       return MM_ERROR_WFD_NO_FREE_SPACE;
+}
+
+
+int mm_wfd_sink_wlclient_get_wl_window_wl_surface_id (wl_client * wlclient, struct wl_surface *surface, struct wl_display *display)
+{
+       goto_if_fail (wlclient != NULL, failed);
+       goto_if_fail (surface != NULL, failed);
+       goto_if_fail (display != NULL, failed);
+
+       unsigned int wl_surface_id = 0;
+
+       wlclient->display = display;
+       goto_if_fail (wlclient->display != NULL, failed);
+
+       wlclient->registry = wl_display_get_registry(wlclient->display);
+       goto_if_fail (wlclient->registry != NULL, failed);
+
+       wl_registry_add_listener(wlclient->registry, &registry_listener, wlclient);
+       wl_display_dispatch(wlclient->display);
+       wl_display_roundtrip(wlclient->display);
+
+       /* check global objects */
+       goto_if_fail (wlclient->tz_surface != NULL, failed);
+
+       /* Get wl_surface_id which is unique in a entire systemw. */
+       wlclient->tz_resource = tizen_surface_get_tizen_resource(wlclient->tz_surface, surface);
+       goto_if_fail (wlclient->tz_resource != NULL, failed);
+
+       tizen_resource_add_listener(wlclient->tz_resource, &tz_resource_listener, &wl_surface_id);
+       wl_display_roundtrip(wlclient->display);
+       goto_if_fail (wl_surface_id > 0, failed);
+
+       mm_wfd_sink_wlclient_finalize(wlclient);
+
+       return wl_surface_id;
+
+failed:
+       wfd_sink_error ("Failed to get wl_surface_id");
+
+       return 0;
+}
+
+void mm_wfd_sink_wlclient_finalize (wl_client * wlclient)
+{
+       wfd_sink_debug ("start finalize wlclient");
+       return_if_fail (wlclient != NULL)
+
+       if (wlclient->tz_surface)
+               tizen_surface_destroy(wlclient->tz_surface);
+
+       if (wlclient->tz_resource)
+               tizen_resource_destroy(wlclient->tz_resource);
+
+    /* destroy registry */
+       if (wlclient->registry)
+               wl_registry_destroy(wlclient->registry);
+       return;
+}