merge with master
authorJinkun Jang <jinkun.jang@samsung.com>
Fri, 15 Mar 2013 16:15:22 +0000 (01:15 +0900)
committerJinkun Jang <jinkun.jang@samsung.com>
Fri, 15 Mar 2013 16:15:22 +0000 (01:15 +0900)
16 files changed:
AUTHORS
COPYING [moved from LICENSE.LGPLv2.1 with 100% similarity]
Makefile.am [changed mode: 0644->0755]
NOTICE [deleted file]
common/m4/gst-x11.m4 [new file with mode: 0644]
configure.ac [changed mode: 0755->0644]
encodebin/src/gstencodebin.c
encodebin/src/gstencodebin.h
evaspixmapsink/Makefile.am [new file with mode: 0644]
evaspixmapsink/evaspixmapsink.c [new file with mode: 0644]
evaspixmapsink/evaspixmapsink.h [new file with mode: 0644]
evaspixmapsink/xv_types.h [new file with mode: 0644]
packaging/gst-plugins-ext0.10.spec
xvimagesrc/src/Makefile.am
xvimagesrc/src/gstxvimagesrc.c [changed mode: 0755->0644]
xvimagesrc/src/gstxvimagesrc.h [changed mode: 0755->0644]

diff --git a/AUTHORS b/AUTHORS
index 6f522a8..96cbfc8 100644 (file)
--- a/AUTHORS
+++ b/AUTHORS
@@ -1,5 +1,5 @@
-JongHyuk Choi <jhchoi.choi at samsung dot com>
-Seungbae Shin <seungbae.shin at samsung dot com>
-Younghwan Ahn <younghwan_.an at samsung dot com>
-Jeongmo Yang <jm80.yang at samsung dot com>
-Sangchul Lee <sc11.lee at samsung dot com>
+JongHyuk Choi <jhchoi.choi@samsung.com>
+Seungbae Shin <seungbae.shin@samsung.com>
+Younghwan Ahn <younghwan_.an@samsung.com>
+Jeongmo Yang <jm80.yang@samsung.com>
+Sangchul Lee <sc11.lee@samsung.com>
similarity index 100%
rename from LICENSE.LGPLv2.1
rename to COPYING
old mode 100644 (file)
new mode 100755 (executable)
index 0673794..16eea53
@@ -17,6 +17,10 @@ if GST_EXT_USE_EXT_EVASIMAGESINK
 SUBDIRS += evasimagesink
 endif
 
+if GST_EXT_USE_EXT_EVASPIXMAPSINK
+SUBDIRS += evaspixmapsink
+endif
+
 if GST_EXT_USE_EXT_XVIMAGESRC
 SUBDIRS += xvimagesrc
 endif
diff --git a/NOTICE b/NOTICE
deleted file mode 100644 (file)
index 0e6ffbb..0000000
--- a/NOTICE
+++ /dev/null
@@ -1,3 +0,0 @@
-Copyright (c) Samsung Electronics Co., Ltd. All rights reserved.
-Except as noted, this software is licensed under GNU LESSER GENERAL PUBLIC LICENSE, Version 2.1
-Please, see the LICENSE file for GNU LESSER GENERAL PUBLIC LICENSE terms and conditions.
diff --git a/common/m4/gst-x11.m4 b/common/m4/gst-x11.m4
new file mode 100644 (file)
index 0000000..d3baf2d
--- /dev/null
@@ -0,0 +1,70 @@
+dnl macros for X-related detections
+dnl AC_SUBST's HAVE_X, X_CFLAGS, X_LIBS
+AC_DEFUN([AG_GST_CHECK_X],
+[
+  AC_PATH_XTRA
+  ac_cflags_save="$CFLAGS"
+  ac_cppflags_save="$CPPFLAGS"
+  CFLAGS="$CFLAGS $X_CFLAGS"
+  CPPFLAGS="$CPPFLAGS $X_CFLAGS"
+
+  dnl now try to find the HEADER
+  AC_CHECK_HEADER(X11/Xlib.h, HAVE_X="yes", HAVE_X="no")
+
+  if test "x$HAVE_X" = "xno"
+  then
+    AC_MSG_NOTICE([cannot find X11 development files])
+  else
+    dnl this is much more than we want
+    X_LIBS="$X_LIBS $X_PRE_LIBS $X_EXTRA_LIBS"
+    dnl AC_PATH_XTRA only defines the path needed to find the X libs,
+    dnl it does not add the libs; therefore we add them here
+    X_LIBS="$X_LIBS -lX11"
+    AC_SUBST(X_CFLAGS)
+    AC_SUBST(X_LIBS)
+  fi
+  AC_SUBST(HAVE_X)
+
+  CFLAGS="$ac_cflags_save"
+  CPPFLAGS="$ac_cppflags_save"
+])
+
+dnl *** XVideo ***
+dnl Look for the PIC library first, Debian requires it.
+dnl Check debian-devel archives for gory details.
+dnl 20020110:
+dnl At the moment XFree86 doesn't distribute shared libXv due
+dnl to unstable API.  On many platforms you CAN NOT link a shared
+dnl lib to a static non-PIC lib.  This is what the xvideo GStreamer
+dnl plug-in wants to do.  So Debian distributes a PIC compiled
+dnl version of the static lib for plug-ins to link to when it is
+dnl inappropriate to link the main application to libXv directly.
+dnl FIXME: add check if this platform can support linking to a
+dnl        non-PIC libXv, if not then don not use Xv.
+dnl FIXME: perhaps warn user if they have a shared libXv since
+dnl        this is an error until XFree86 starts shipping one
+AC_DEFUN([AG_GST_CHECK_XV],
+[
+  if test x$HAVE_X = xyes; then
+    AC_CHECK_LIB(Xv_pic, XvQueryExtension,
+                 HAVE_XVIDEO="yes", HAVE_XVIDEO="no",
+                 $X_LIBS -lXext)
+
+    if test x$HAVE_XVIDEO = xyes; then
+      XVIDEO_LIBS="-lXv_pic -lXext"
+      AC_SUBST(XVIDEO_LIBS)
+    else
+      dnl try again using something else if we didn't find it first
+      if test x$HAVE_XVIDEO = xno; then
+        AC_CHECK_LIB(Xv, XvQueryExtension,
+                   HAVE_XVIDEO="yes", HAVE_XVIDEO="no",
+                   $X_LIBS -lXext)
+
+        if test x$HAVE_XVIDEO = xyes; then
+          XVIDEO_LIBS="-lXv -lXext"
+          AC_SUBST(XVIDEO_LIBS)
+        fi
+      fi
+    fi
+  fi
+])
old mode 100755 (executable)
new mode 100644 (file)
index c57ef7f..3cd2352
@@ -190,16 +190,16 @@ PKG_CHECK_MODULES(DRM, libdrm-devel)
 AC_SUBST(DRM_DEVEL_CFLAGS)
 AC_SUBST(DRM_DEVEL_LIBS)
 
-PKG_CHECK_MODULES(DRM_SLP, libdrm_slp)
-AC_SUBST(DRM_SLP_CFLAGS)
-AC_SUBST(DRM_SLP_LIBS)
+PKG_CHECK_MODULES(TBM, libtbm)
+AC_SUBST(TBM_CFLAGS)
+AC_SUBST(TBM_LIBS)
 
 dnl use time analysis module
 PKG_CHECK_MODULES(MMTA, mm-ta)
 AC_SUBST(MMTA_CFLAGS)
 AC_SUBST(MMTA_LIBS)
 
-dnl required package for evasimagesink
+dnl required package for evasimagesink/evaspixmapsink
 PKG_CHECK_MODULES(EFL, [
   evas >= $EFL_REQUIRED
   ecore >= $EFL_REQUIRED
@@ -216,6 +216,79 @@ PKG_CHECK_MODULES(EFL, [
   ])
 ])
 
+dnl *** belows are related to evaspixmapsink plug-ins ***
+AG_GST_ARG_WITH_PACKAGE_NAME
+AG_GST_ARG_WITH_PACKAGE_ORIGIN
+
+dnl set license and copyright notice
+GST_LICENSE="LGPL"
+AC_DEFINE_UNQUOTED(GST_LICENSE, "$GST_LICENSE", [GStreamer license])
+AC_SUBST(GST_LICENSE)
+
+echo
+AC_MSG_NOTICE([Checking libraries for evaspixmapsink plugin])
+echo
+dnl *** X11 ***
+translit(dnm, m, l) AM_CONDITIONAL(USE_X, true)
+AG_GST_CHECK_FEATURE(X, [X libraries and plugins],
+                  [evaspixmapsink], [
+  AC_PATH_XTRA
+  ac_cflags_save="$CFLAGS"
+  ac_cppflags_save="$CPPFLAGS"
+  CFLAGS="$CFLAGS $X_CFLAGS"
+  CPPFLAGS="$CPPFLAGS $X_CFLAGS"
+
+  dnl now try to find the HEADER
+  AC_CHECK_HEADER(X11/Xlib.h, HAVE_X="yes", HAVE_X="no")
+
+  if test "x$HAVE_X" = "xno"
+  then
+    AC_MSG_NOTICE([cannot find X11 development files])
+  else
+    dnl this is much more than we want
+    X_LIBS="$X_LIBS $X_PRE_LIBS $X_EXTRA_LIBS"
+    dnl AC_PATH_XTRA only defines the path needed to find the X libs,
+    dnl it does not add the libs; therefore we add them here
+    X_LIBS="$X_LIBS -lX11"
+    AC_SUBST(X_CFLAGS)
+    AC_SUBST(X_LIBS)
+  fi
+  AC_SUBST(HAVE_X)
+  CFLAGS="$ac_cflags_save"
+  CPPFLAGS="$ac_cppflags_save"
+])
+
+dnl Check for Xv extension
+translit(dnm, m, l) AM_CONDITIONAL(USE_XVIDEO, true)
+AG_GST_CHECK_FEATURE(XVIDEO, [X11 XVideo extensions],
+                  [evaspixmapsink], [
+AG_GST_CHECK_XV
+])
+
+dnl check for X Shm
+translit(dnm, m, l) AM_CONDITIONAL(USE_XSHM, true)
+AG_GST_CHECK_FEATURE(XSHM, [X Shared Memory extension], , [
+  if test x$HAVE_X = xyes; then
+    AC_CHECK_LIB(Xext, XShmAttach,
+                HAVE_XSHM="yes", HAVE_XSHM="no",
+                $X_LIBS)
+    if test "x$HAVE_XSHM" = "xyes"; then
+      XSHM_LIBS="-lXext"
+    else
+      dnl On AIX, it is in XextSam instead, but we still need -lXext
+      AC_CHECK_LIB(XextSam, XShmAttach,
+                  HAVE_XSHM="yes", HAVE_XSHM="no",
+                  $X_LIBS)
+      if test "x$HAVE_XSHM" = "xyes"; then
+       XSHM_LIBS="-lXext -lXextSam"
+      fi
+    fi
+  fi
+], , [
+  AC_SUBST(HAVE_XSHM)
+  AC_SUBST(XSHM_LIBS)
+])
+
 dnl PKG_CHECK_MODULES(UDEVMGR, unified-dev-mgr)
 dnl AC_SUBST(UDEVMGR_CFLAGS)
 dnl AC_SUBST(UDEVMGR_LIBS)
@@ -256,6 +329,18 @@ AC_ARG_ENABLE(ext-evasimagesink, AC_HELP_STRING([--enable-ext-evasimagesink], [u
   [GST_EXT_USE_EXT_EVASIMAGESINK=yes])
 AM_CONDITIONAL(GST_EXT_USE_EXT_EVASIMAGESINK, test "x$GST_EXT_USE_EXT_EVASIMAGESINK" = "xyes")
 
+dnl use evaspixmapsink ---------------------------------------------------------------------------
+AC_ARG_ENABLE(ext-evaspixmapsink, AC_HELP_STRING([--enable-ext-evaspixmapsink], [using evaspixmapsink]),
+  [
+    case "${enableval}" in
+      yes) GST_EXT_USE_EXT_EVASPIXMAPSINK=yes ;;
+      no)  GST_EXT_USE_EXT_EVASPIXMAPSINK=no ;;
+      *)   AC_MSG_ERROR(bad value ${enableval} for --enable-ext-evaspixmapsink) ;;
+    esac
+  ],
+  [GST_EXT_USE_EXT_EVASPIXMAPSINK=yes])
+AM_CONDITIONAL(GST_EXT_USE_EXT_EVASPIXMAPSINK, test "x$GST_EXT_USE_EXT_EVASPIXMAPSINK" = "xyes")
+
 dnl use ext-xvimagesrc--------------------------------------------------------------------------
 AC_ARG_ENABLE(ext-xvimagesrc, AC_HELP_STRING([--enable-ext-xvimagesrc], [using xvimagesrc]),
   [
@@ -375,6 +460,7 @@ encodebin/Makefile
 encodebin/src/Makefile
 evasimagesink/Makefile
 evasimagesink/src/Makefile
+evaspixmapsink/Makefile
 xvimagesrc/Makefile
 xvimagesrc/src/Makefile
 toggle/Makefile
index 9539702..5ee9617 100644 (file)
@@ -78,12 +78,13 @@ g_object_set(G_OBJECT(x_queue), \
       gst_object_unref( sinkpad ); sinkpad = NULL;\
 }
 
-#define DEFAULT_PROP_PROFILE             0
-#define DEFAULT_PROP_HIGH_SPEED                0
-#define DEFAULT_PROP_VENC_NAME "ffenc_h263"
-#define DEFAULT_PROP_AENC_NAME "secenc_amr"
-#define DEFAULT_PROP_IENC_NAME "jpegenc"
-#define DEFAULT_PROP_MUX_NAME  "ffmux_3gp" 
+#define DEFAULT_PROP_PROFILE            0
+#define DEFAULT_PROP_HIGH_SPEED         0
+#define DEFAULT_PROP_VENC_NAME          "ffenc_h263"
+#define DEFAULT_PROP_AENC_NAME          "secenc_amr"
+#define DEFAULT_PROP_IENC_NAME          "jpegenc"
+#define DEFAULT_PROP_MUX_NAME           "ffmux_3gp"
+#define DEFAULT_PROP_VCONV_NAME         "ffmpegcolorspace"
 
 /* props */
 enum
@@ -96,8 +97,9 @@ enum
        //elements name
        PROP_VENC_NAME,
        PROP_AENC_NAME,
-       PROP_IENC_NAME, 
-       PROP_MUX_NAME, 
+       PROP_IENC_NAME,
+       PROP_MUX_NAME,
+       PROP_VCONV_NAME,
        //caps
        PROP_VCAPS,
        PROP_ACAPS,
@@ -108,13 +110,14 @@ enum
        PROP_AUTO_COLORSPACE,
        PROP_BLOCK,
        PROP_PAUSE,
-       PROP_VENC_QUEUE,        
+       PROP_VENC_QUEUE,
        PROP_AENC_QUEUE,
        //elements pointer
        PROP_VIDEO_ENC,
        PROP_AUDIO_ENC,
        PROP_IMAGE_ENC,
        PROP_MUX,
+       PROP_VIDEO_CONV,
        //options
        PROP_USE_VIDEO_TOGGLE,
 };
@@ -135,7 +138,8 @@ typedef enum {
        ENCODEBIN_ELEMENT_VENC,
        ENCODEBIN_ELEMENT_AENC,
        ENCODEBIN_ELEMENT_IENC,
-       ENCODEBIN_ELEMENT_MUX
+       ENCODEBIN_ELEMENT_MUX,
+       ENCODEBIN_ELEMENT_VIDEO_CONV
 }GstEncodeBinElement;
 
 typedef enum {
@@ -573,7 +577,10 @@ gst_encode_bin_get_property (GObject * object,
                        break; 
                case PROP_MUX_NAME:
                        g_value_set_string (value, encodebin->mux_name);
-                       break; 
+                       break;
+               case PROP_VCONV_NAME:
+                       g_value_set_string (value, encodebin->vconv_name);
+                       break;
                //caps
                case PROP_VCAPS:
                        gst_value_set_caps (value, encodebin->vcaps);
@@ -613,16 +620,16 @@ gst_encode_bin_get_property (GObject * object,
 //                     g_value_set_boolean (value, encodebin->use_aenc_queue);
                        if((encodebin->audio_encode_queue == NULL) && (encodebin->profile <= GST_ENCODE_BIN_PROFILE_AUDIO)) {
                                encodebin->audio_encode_queue = gst_element_factory_make ("queue", "audio_encode_queue");
-                               if(encodebin->audio_encode_queue != NULL) 
+                               if(encodebin->audio_encode_queue != NULL)
                                        gst_bin_add(GST_BIN(encodebin), encodebin->audio_encode_queue);
                        }
-                       g_value_set_object (value, encodebin->audio_encode_queue);                                      
-                       break;                                          
+                       g_value_set_object (value, encodebin->audio_encode_queue);
+                       break;
                //elements pointer
                case PROP_VIDEO_ENC:
                        if((encodebin->video_encode == NULL) && (encodebin->profile == GST_ENCODE_BIN_PROFILE_AV)) {
                                encodebin->video_encode = gst_element_factory_make (encodebin->venc_name, "video_encode");
-                               if(encodebin->video_encode != NULL) 
+                               if(encodebin->video_encode != NULL)
                                        gst_bin_add(GST_BIN(encodebin), encodebin->video_encode);
                        }
                        g_value_set_object (value, encodebin->video_encode);
@@ -630,7 +637,7 @@ gst_encode_bin_get_property (GObject * object,
                case PROP_AUDIO_ENC:
                        if(encodebin->audio_encode == NULL && (encodebin->profile <= GST_ENCODE_BIN_PROFILE_AUDIO)) {
                                encodebin->audio_encode = gst_element_factory_make (encodebin->aenc_name, "audio_encode");
-                               if(encodebin->audio_encode != NULL) 
+                               if(encodebin->audio_encode != NULL)
                                        gst_bin_add(GST_BIN(encodebin), encodebin->audio_encode);
                        }
                        g_value_set_object (value, encodebin->audio_encode);
@@ -638,7 +645,7 @@ gst_encode_bin_get_property (GObject * object,
                case PROP_IMAGE_ENC:
                        if(encodebin->image_encode == NULL && (encodebin->profile == GST_ENCODE_BIN_PROFILE_IMAGE)) {
                                encodebin->image_encode = gst_element_factory_make (encodebin->ienc_name, "image_encode");
-                               if(encodebin->image_encode != NULL) 
+                               if(encodebin->image_encode != NULL)
                                        gst_bin_add(GST_BIN(encodebin), encodebin->image_encode);
                        }
                        g_value_set_object (value, encodebin->image_encode);
@@ -646,11 +653,19 @@ gst_encode_bin_get_property (GObject * object,
                case PROP_MUX:
                        if(encodebin->mux == NULL && (encodebin->profile <= GST_ENCODE_BIN_PROFILE_AUDIO)) {
                                encodebin->mux = gst_element_factory_make (encodebin->mux_name, "mux");
-                               if(encodebin->mux != NULL) 
+                               if(encodebin->mux != NULL)
                                        gst_bin_add(GST_BIN(encodebin), encodebin->mux);
                        }
                        g_value_set_object (value, encodebin->mux);
                        break;
+               case PROP_VIDEO_CONV:
+                       if(encodebin->color_space == NULL && (encodebin->profile != GST_ENCODE_BIN_PROFILE_AUDIO)) {
+                               encodebin->color_space = gst_element_factory_make (encodebin->vconv_name, "video_convert");
+                               if(encodebin->color_space != NULL)
+                                       gst_bin_add(GST_BIN(encodebin), encodebin->color_space);
+                       }
+                       g_value_set_object (value, encodebin->color_space);
+                       break;
                case PROP_USE_VIDEO_TOGGLE:
                        g_value_set_boolean( value, encodebin->use_video_toggle );
                        break;
@@ -691,13 +706,13 @@ gst_encode_bin_set_property (GObject * object,
                        new_name = g_value_get_string (value);
 
                        if(encodebin->video_encode == NULL) {
-                               if(gst_encode_bin_add_element_by_name(encodebin, ENCODEBIN_ELEMENT_VENC, new_name))             
+                               if(gst_encode_bin_add_element_by_name(encodebin, ENCODEBIN_ELEMENT_VENC, new_name))
                                        encodebin->venc_name = g_strdup (new_name);
                        } else {
                                if(strcmp (encodebin->venc_name, new_name)) {
                                        gst_encode_bin_remove_element(encodebin, encodebin->video_encode);
-                                       if(gst_encode_bin_add_element_by_name(encodebin, ENCODEBIN_ELEMENT_VENC, new_name))             
-                                       encodebin->venc_name = g_strdup (new_name);
+                                       if(gst_encode_bin_add_element_by_name(encodebin, ENCODEBIN_ELEMENT_VENC, new_name))
+                                               encodebin->venc_name = g_strdup (new_name);
                                }
                        }
                        break;
@@ -717,7 +732,7 @@ gst_encode_bin_set_property (GObject * object,
                                if(strcmp (encodebin->aenc_name, new_name)) {
                                        gst_encode_bin_remove_element(encodebin, encodebin->audio_encode);
                                        if(gst_encode_bin_add_element_by_name(encodebin, ENCODEBIN_ELEMENT_AENC, new_name))             
-                                       encodebin->aenc_name = g_strdup (new_name);
+                                               encodebin->aenc_name = g_strdup (new_name);
                                }
                        }
                        break;
@@ -737,7 +752,7 @@ gst_encode_bin_set_property (GObject * object,
                                if(strcmp (encodebin->ienc_name, new_name)) {
                                        gst_encode_bin_remove_element(encodebin, encodebin->image_encode);
                                        if(gst_encode_bin_add_element_by_name(encodebin, ENCODEBIN_ELEMENT_IENC, new_name))             
-                                       encodebin->ienc_name = g_strdup (new_name);
+                                               encodebin->ienc_name = g_strdup (new_name);
                                }
                        }
                        break; 
@@ -751,16 +766,36 @@ gst_encode_bin_set_property (GObject * object,
                        new_name = g_value_get_string (value);
 
                        if(encodebin->mux == NULL) {
-                               if(gst_encode_bin_add_element_by_name(encodebin, ENCODEBIN_ELEMENT_MUX, new_name))              
+                               if(gst_encode_bin_add_element_by_name(encodebin, ENCODEBIN_ELEMENT_MUX, new_name))
                                        encodebin->mux_name = g_strdup (new_name);
                        } else {
                                if(strcmp (encodebin->mux_name, new_name)) {
                                        gst_encode_bin_remove_element(encodebin, encodebin->mux);
-                                       if(gst_encode_bin_add_element_by_name(encodebin, ENCODEBIN_ELEMENT_MUX, new_name))              
-                                       encodebin->mux_name = g_strdup (new_name);
+                                       if(gst_encode_bin_add_element_by_name(encodebin, ENCODEBIN_ELEMENT_MUX, new_name))
+                                               encodebin->mux_name = g_strdup (new_name);
                                }
                        }
-                       break; 
+                       break;
+               }
+               case PROP_VCONV_NAME: {
+                       const gchar  *new_name;
+                       if (encodebin->profile == GST_ENCODE_BIN_PROFILE_AUDIO) {
+                               GST_WARNING_OBJECT(encodebin, "Profile isn't match");
+                               break;
+                       }
+                       new_name = g_value_get_string(value);
+
+                       if (encodebin->color_space == NULL) {
+                               if(gst_encode_bin_add_element_by_name(encodebin, ENCODEBIN_ELEMENT_VIDEO_CONV, new_name))
+                                       encodebin->vconv_name = g_strdup (new_name);
+                       } else {
+                               if(strcmp (encodebin->vconv_name, new_name)) {
+                                       gst_encode_bin_remove_element(encodebin, encodebin->color_space);
+                                       if(gst_encode_bin_add_element_by_name(encodebin, ENCODEBIN_ELEMENT_VIDEO_CONV, new_name))
+                                               encodebin->vconv_name = g_strdup (new_name);
+                               }
+                       }
+                       break;
                }
                //caps
                case PROP_VCAPS: {
@@ -960,6 +995,21 @@ gst_encode_bin_set_property (GObject * object,
                        }
                        break;
                }
+               case PROP_VIDEO_CONV: {
+                       GstElement *newelement = g_value_get_object (value);
+                       if(encodebin->profile == GST_ENCODE_BIN_PROFILE_AUDIO) {
+                               GST_WARNING_OBJECT(encodebin, "Profile isn't match, change profile first!");
+                               break;
+                       }
+                       if(newelement != NULL) {
+                               gst_encode_bin_remove_element(encodebin, encodebin->color_space);
+                               encodebin->color_space = newelement;
+                               gst_object_ref (encodebin->color_space);
+                               gst_object_sink (GST_OBJECT_CAST (encodebin->color_space));
+                               gst_bin_add(GST_BIN(encodebin), encodebin->color_space);
+                       }
+                       break;
+               }
                case PROP_USE_VIDEO_TOGGLE:
                        encodebin->use_video_toggle = g_value_get_boolean( value );
                        break;
@@ -1084,7 +1134,6 @@ gst_encode_bin_request_new_pad (GstElement * element,
 static void
 gst_encode_bin_class_init (GstEncodeBinClass *klass)
 {
-
        GObjectClass *gobject_klass;
        GstElementClass *gstelement_klass;
        GstBinClass *gstbin_klass;
@@ -1126,6 +1175,10 @@ gst_encode_bin_class_init (GstEncodeBinClass *klass)
          g_param_spec_string ("mux-name", "muxer name", "the name of muxer to use",
              DEFAULT_PROP_MUX_NAME, G_PARAM_READWRITE));
 
+       g_object_class_install_property (gobject_klass, PROP_VCONV_NAME,
+         g_param_spec_string ("vconv-name", "Video converter name", "the name of video color converter to use",
+             DEFAULT_PROP_VCONV_NAME, G_PARAM_READWRITE));
+
        g_object_class_install_property (gobject_klass, PROP_VCAPS,
          g_param_spec_boxed ("vcaps", "caps for video","caps for video recording",
              GST_TYPE_CAPS, G_PARAM_READWRITE));
@@ -1198,6 +1251,11 @@ gst_encode_bin_class_init (GstEncodeBinClass *klass)
              "the muxer element to use",
              GST_TYPE_ELEMENT, G_PARAM_READWRITE));
 
+       g_object_class_install_property (gobject_klass, PROP_VIDEO_CONV,
+         g_param_spec_object ("video-convert", "Video converter",
+             "the video converter element to use",
+             GST_TYPE_ELEMENT, G_PARAM_READWRITE));
+
        g_object_class_install_property (gobject_klass, PROP_USE_VIDEO_TOGGLE,
                g_param_spec_boolean ("use-video-toggle", "Use video toggle",
                "Use video toggle while AV recording", TRUE, G_PARAM_READWRITE));
@@ -1248,10 +1306,10 @@ gst_encode_bin_init (GstEncodeBin *encodebin)
 {
        encodebin->mutex = g_mutex_new();
 
-       if(encodebin->srcpad == NULL) {
+       if (encodebin->srcpad == NULL) {
                encodebin->srcpad = gst_ghost_pad_new_no_target ("src", GST_PAD_SRC);
                gst_element_add_pad (GST_ELEMENT(encodebin), encodebin->srcpad);
-       }  
+       }
 
        encodebin->video_sinkpad = NULL;
        encodebin->audio_sinkpad = NULL;
@@ -1268,37 +1326,38 @@ gst_encode_bin_init (GstEncodeBin *encodebin)
        encodebin->auto_audio_resample = TRUE;
        encodebin->auto_color_space = TRUE;
        encodebin->block = FALSE;
-       encodebin->pause= FALSE; 
+       encodebin->pause= FALSE;
        encodebin->use_video_toggle = TRUE;
-       encodebin->use_venc_queue= FALSE;       
-       encodebin->use_aenc_queue= FALSE;               
+       encodebin->use_venc_queue= FALSE;
+       encodebin->use_aenc_queue= FALSE;
 
        encodebin->venc_name = g_strdup(DEFAULT_PROP_VENC_NAME);
        encodebin->aenc_name = g_strdup(DEFAULT_PROP_AENC_NAME);
-       encodebin->ienc_name = g_strdup(DEFAULT_PROP_IENC_NAME);  
-       encodebin->mux_name = g_strdup(DEFAULT_PROP_MUX_NAME);  
+       encodebin->ienc_name = g_strdup(DEFAULT_PROP_IENC_NAME);
+       encodebin->mux_name = g_strdup(DEFAULT_PROP_MUX_NAME);
+       encodebin->vconv_name = g_strdup(DEFAULT_PROP_VCONV_NAME);
 
        encodebin->vcaps = gst_caps_new_any ();
        encodebin->acaps = gst_caps_new_any ();
        encodebin->icaps = gst_caps_new_any ();
 
        encodebin->audio_queue = NULL;
-       encodebin->video_queue = NULL;  
-       encodebin->video_encode_queue = NULL;   
-       encodebin->image_queue = NULL;    
+       encodebin->video_queue = NULL;
+       encodebin->video_encode_queue = NULL;
+       encodebin->image_queue = NULL;
 
        encodebin->audio_encode = NULL;
        encodebin->video_encode = NULL;
-       encodebin->image_encode = NULL;  
+       encodebin->image_encode = NULL;
 
-       encodebin->vcapsfilter = NULL;  
-       encodebin->acapsfilter = NULL;    
-       encodebin->icapsfilter = NULL;      
+       encodebin->vcapsfilter = NULL;
+       encodebin->acapsfilter = NULL;
+       encodebin->icapsfilter = NULL;
 
-       encodebin->video_toggle = NULL;  
+       encodebin->video_toggle = NULL;
        encodebin->image_toggle = NULL;
-       encodebin->color_space = NULL;  
-       encodebin->audio_conv = NULL;  
+       encodebin->color_space = NULL;
+       encodebin->audio_conv = NULL;
        encodebin->audio_sample = NULL;
 
        encodebin->mux = NULL;
@@ -1310,11 +1369,11 @@ gst_encode_bin_init (GstEncodeBin *encodebin)
        encodebin->vsink_hs_probeid = 0;
        encodebin->asink_probeid = 0;
        encodebin->veque_sig_id = 0;
-       encodebin->aeque_sig_id = 0;    
+       encodebin->aeque_sig_id = 0;
 }
 
-static void 
-gst_encode_bin_dispose (GObject * object) 
+static void
+gst_encode_bin_dispose (GObject * object)
 {
        GstEncodeBin *encodebin = GST_ENCODE_BIN (object);
 
@@ -1330,22 +1389,20 @@ gst_encode_bin_dispose (GObject * object)
        g_free(encodebin->mux_name);
        encodebin->mux_name = NULL;
 
+       g_free(encodebin->vconv_name);
+       encodebin->vconv_name = NULL;
 
        gst_caps_replace (&encodebin->vcaps, NULL);
        gst_caps_replace (&encodebin->acaps, NULL);
        gst_caps_replace (&encodebin->icaps, NULL);
 
-       if(encodebin->srcpad != NULL)
-       {
-               gst_element_remove_pad (GST_ELEMENT(encodebin), encodebin->srcpad);
+       if (encodebin->srcpad != NULL) {
+               gst_element_remove_pad(GST_ELEMENT(encodebin), encodebin->srcpad);
                encodebin->srcpad = NULL;
        }
-               
 
        G_OBJECT_CLASS (parent_class)->dispose (object);
 
-
-
        encodebin->video_sinkpad = NULL;
        encodebin->audio_sinkpad = NULL;
        encodebin->image_sinkpad = NULL;
@@ -1353,34 +1410,33 @@ gst_encode_bin_dispose (GObject * object)
        encodebin->mux_video_sinkpad = NULL;
 
        encodebin->audio_queue = NULL;
-       encodebin->video_queue = NULL;  
-       encodebin->image_queue = NULL;    
+       encodebin->video_queue = NULL;
+       encodebin->image_queue = NULL;
 
        encodebin->audio_encode = NULL;
        encodebin->video_encode = NULL;
-       encodebin->video_encode_queue = NULL;   
-       encodebin->image_encode = NULL;  
+       encodebin->video_encode_queue = NULL;
+       encodebin->image_encode = NULL;
 
-       encodebin->vcapsfilter = NULL;  
-       encodebin->acapsfilter = NULL;    
-       encodebin->icapsfilter = NULL;      
+       encodebin->vcapsfilter = NULL;
+       encodebin->acapsfilter = NULL;
+       encodebin->icapsfilter = NULL;
 
-       encodebin->video_toggle = NULL;  
+       encodebin->video_toggle = NULL;
        encodebin->image_toggle = NULL;
-       encodebin->color_space = NULL;  
-       encodebin->audio_conv = NULL;  
+       encodebin->color_space = NULL;
+       encodebin->audio_conv = NULL;
        encodebin->audio_sample = NULL;
        
-       if(encodebin->mux && GST_IS_ELEMENT(encodebin->mux))
-       {
-               int remain_count= 0 ;
+       if (encodebin->mux && GST_IS_ELEMENT(encodebin->mux)) {
+               int remain_count= 0;
                remain_count = GST_OBJECT_REFCOUNT_VALUE(encodebin->mux);
-               while(remain_count)
-               {
+               while (remain_count) {
                        gst_object_unref(encodebin->mux);
                        remain_count--;
-               }               
+               }
        }
+
        encodebin->mux = NULL;
 }
 
@@ -1563,45 +1619,59 @@ static gboolean
 gst_encode_bin_add_element_by_name (GstEncodeBin *encodebin, GstEncodeBinElement type, const gchar *name)
 {
        switch(type) {
-               case ENCODEBIN_ELEMENT_VENC :
-                       encodebin->video_encode = gst_element_factory_make (name, "video_encode");      
+               case ENCODEBIN_ELEMENT_VENC:
+                       encodebin->video_encode = gst_element_factory_make (name, "video_encode");
                        if(encodebin->video_encode != NULL) {
                                gst_bin_add(GST_BIN(encodebin), encodebin->video_encode);
                                g_free(encodebin->venc_name);
+                               encodebin->venc_name = NULL;
                        } else {
                                goto element_make_fail;
                        }
                        break;
-               case ENCODEBIN_ELEMENT_AENC :
-                       encodebin->audio_encode = gst_element_factory_make (name, "audio_encode");      
+               case ENCODEBIN_ELEMENT_AENC:
+                       encodebin->audio_encode = gst_element_factory_make (name, "audio_encode");
                        if(encodebin->audio_encode != NULL) {
                                gst_bin_add(GST_BIN(encodebin), encodebin->audio_encode);
                                g_free(encodebin->aenc_name);
+                               encodebin->aenc_name = NULL;
                        } else {
                                goto element_make_fail;
-                       }                       
+                       }
                        break;
-               case ENCODEBIN_ELEMENT_IENC :
-                       encodebin->image_encode = gst_element_factory_make (name, "image_encode");      
+               case ENCODEBIN_ELEMENT_IENC:
+                       encodebin->image_encode = gst_element_factory_make (name, "image_encode");
                        if(encodebin->image_encode != NULL) {
                                gst_bin_add(GST_BIN(encodebin), encodebin->image_encode);
                                g_free(encodebin->ienc_name);
+                               encodebin->ienc_name = NULL;
                        } else {
                                goto element_make_fail;
-                       }               
+                       }
                        break;
-               case ENCODEBIN_ELEMENT_MUX :
-                       encodebin->mux = gst_element_factory_make (name, "mux");        
+               case ENCODEBIN_ELEMENT_MUX:
+                       encodebin->mux = gst_element_factory_make (name, "mux");
                        if(encodebin->mux != NULL) {
                                gst_bin_add(GST_BIN(encodebin), encodebin->mux);
                                g_free(encodebin->mux_name);
+                               encodebin->mux_name = NULL;
+                       } else {
+                               goto element_make_fail;
+                       }
+                       break;
+               case ENCODEBIN_ELEMENT_VIDEO_CONV:
+                       encodebin->color_space = gst_element_factory_make(name, "video_convert");
+                       if (encodebin->color_space != NULL) {
+                               gst_bin_add(GST_BIN(encodebin), encodebin->color_space);
+                               g_free(encodebin->vconv_name);
+                               encodebin->vconv_name = NULL;
                        } else {
                                goto element_make_fail;
-                       }               
+                       }
                        break;
-               default :       
+               default:
                        GST_WARNING_OBJECT(encodebin, "Invalid element type = %d", type);
-                       break;  
+                       break;
        }
 
        return TRUE;
@@ -1824,10 +1894,12 @@ gst_encode_bin_remove_element (GstEncodeBin *encodebin, GstElement * element)
 {
        GstObject *parent;
        gchar *ename = NULL;
-       GST_DEBUG_OBJECT (encodebin, "gst_encode_bin_remove_element");
+       GST_INFO_OBJECT (encodebin, "gst_encode_bin_remove_element");
 
-       if(element == NULL)
+       if (element == NULL) {
+               GST_INFO_OBJECT (encodebin, "element is already NULL");
                return TRUE;
+       }
 
        gst_element_set_state (element, GST_STATE_NULL);
        parent = gst_element_get_parent (element);
@@ -1839,11 +1911,13 @@ gst_encode_bin_remove_element (GstEncodeBin *encodebin, GstElement * element)
                        GST_ERROR_OBJECT (encodebin, "gst_encode_bin_remove_element() [%s] remove fail", ename);
                        g_free (ename);
                        return FALSE;
-               } else
-                       gst_object_unref (parent);
+               } else {
+                       gst_object_unref(parent);
+               }
        } else {
                gst_object_unref(element);
        }
+
        return TRUE;
   }
 
@@ -1853,18 +1927,25 @@ gst_encode_bin_link_elements (GstEncodeBin *encodebin)  // need to return ????
        GstPad *srcpad = NULL, *sinkpad = NULL;
        switch(encodebin->profile) {
                case GST_ENCODE_BIN_PROFILE_AV :
-                       if(!gst_caps_is_any(encodebin->vcaps))
-                       {
+                       if (!gst_caps_is_any(encodebin->vcaps)) {
+                               gchar *caps_str = NULL;
+                               caps_str = gst_caps_to_string(encodebin->vcaps);
+                               if (caps_str) {
+                                       GST_INFO_OBJECT(encodebin, "vconv caps [%s]", caps_str);
+                                       g_free(caps_str);
+                                       caps_str = NULL;
+                               }
+
                                g_object_set(encodebin->vcapsfilter, "caps", encodebin->vcaps, NULL);
                        }
-       
+
                        if (encodebin->auto_color_space) {
                                if(encodebin->color_space == NULL) {
-                                   encodebin->color_space  = gst_element_factory_make ("ffmpegcolorspace","color_space");
-                                   gst_bin_add (GST_BIN (encodebin), encodebin->color_space);
+                                       encodebin->color_space = gst_element_factory_make (encodebin->vconv_name, "video_convert");
+                                       gst_bin_add (GST_BIN (encodebin), encodebin->color_space);
                                }
-                               
-                               srcpad = gst_element_get_static_pad(encodebin->video_queue, "src");                             
+
+                               srcpad = gst_element_get_static_pad(encodebin->video_queue, "src");
                                if( encodebin->video_toggle )
                                {
                                        sinkpad = gst_element_get_static_pad(encodebin->video_toggle, "sink");
@@ -1877,11 +1958,11 @@ gst_encode_bin_link_elements (GstEncodeBin *encodebin)  // need to return ????
 
                                srcpad = gst_element_get_static_pad(encodebin->color_space, "src");
                                sinkpad = gst_element_get_static_pad(encodebin->vcapsfilter, "sink");
-                               _GST_PAD_LINK_UNREF(srcpad, sinkpad, video_link_fail);  
+                               _GST_PAD_LINK_UNREF(srcpad, sinkpad, video_link_fail);
 
                                srcpad = gst_element_get_static_pad(encodebin->vcapsfilter, "src");
                                sinkpad = gst_element_get_static_pad(encodebin->video_encode, "sink");
-                               _GST_PAD_LINK_UNREF(srcpad, sinkpad, video_link_fail);                                  
+                               _GST_PAD_LINK_UNREF(srcpad, sinkpad, video_link_fail);
 #if 0
                                if(encodebin->use_venc_queue)
                                {
@@ -2347,46 +2428,39 @@ gst_encode_bin_unlink_elements (GstEncodeBin *encodebin)
        switch(encodebin->profile) {
                case GST_ENCODE_BIN_PROFILE_AV :
                        if (encodebin->auto_color_space) {
-                               if( encodebin->video_toggle )
-                               {
-                                       gst_element_unlink_many  (
+                               if (encodebin->video_toggle) {
+                                       gst_element_unlink_many(
                                                encodebin->video_queue,
                                                encodebin->video_toggle,
                                                encodebin->color_space,
-                                               encodebin->vcapsfilter,                                                         
+                                               encodebin->vcapsfilter,
                                                encodebin->video_encode,
-                                               //encodebin->video_encode_queue,                                        
+                                               //encodebin->video_encode_queue,
                                                NULL);
-                               }
-                               else
-                               {
+                               } else {
                                        gst_element_unlink_many(
                                                encodebin->video_queue,
                                                encodebin->color_space,
-                                               encodebin->vcapsfilter,                                                         
+                                               encodebin->vcapsfilter,
                                                encodebin->video_encode,
-                                               //encodebin->video_encode_queue,                                        
+                                               //encodebin->video_encode_queue,
                                                NULL);
                                }
-                       }
-                       else {
-                               if( encodebin->video_toggle )
-                               {
-                                       gst_element_unlink_many  (
+                       } else {
+                               if (encodebin->video_toggle) {
+                                       gst_element_unlink_many(
                                                encodebin->video_queue,
                                                encodebin->video_toggle,
-                                               encodebin->vcapsfilter,                                                         
+                                               encodebin->vcapsfilter,
                                                encodebin->video_encode,
-                                               //encodebin->video_encode_queue,                                                
+                                               //encodebin->video_encode_queue,
                                                NULL);
-                               }
-                               else
-                               {
+                               } else {
                                        gst_element_unlink_many(
                                                encodebin->video_queue,
-                                               encodebin->vcapsfilter,                                                         
+                                               encodebin->vcapsfilter,
                                                encodebin->video_encode,
-                                               //encodebin->video_encode_queue,                                                
+                                               //encodebin->video_encode_queue,
                                                NULL);
                                }
                        }
index 64c3a64..136fc92 100644 (file)
@@ -69,72 +69,72 @@ struct _GstEncodeBin
   GMutex *mutex;
 
   /* pads */
-  GstPad              *srcpad;
-  GstPad              *video_sinkpad;
-  GstPad              *audio_sinkpad;
-  GstPad              *image_sinkpad;
-  GstPad              *mux_audio_sinkpad;
-  GstPad              *mux_video_sinkpad;
+  GstPad *srcpad;
+  GstPad *video_sinkpad;
+  GstPad *audio_sinkpad;
+  GstPad *image_sinkpad;
+  GstPad *mux_audio_sinkpad;
+  GstPad *mux_video_sinkpad;
 
   /* sinkpads, video first */
-  GSList              *sinkpads;
+  GSList *sinkpads;
 
   /* video restricted to 1 pad */
-  guint               video_pads, audio_pads;
-
-  gint         profile;
-  gint         fps;
-  gint         high_speed_fps; 
-  gint         multiple;  
-  gchar                *venc_name;
-  gchar                *aenc_name;
-  gchar                *ienc_name;  
-  gchar                *mux_name;
-
-
-  GstCaps      *vcaps;
-  GstCaps      *acaps;
-  GstCaps      *icaps;
-  
-  gboolean     auto_audio_convert;
-  gboolean     auto_audio_resample;
-  gboolean     auto_color_space;
-  gboolean     block;
-  gboolean     pause;
-  gboolean     use_video_toggle;
-  gboolean     use_venc_queue;
-  gboolean     use_aenc_queue;  
-  
+  guint video_pads, audio_pads;
+
+  gint profile;
+  gint fps;
+  gint high_speed_fps;
+  gint multiple;
+  gchar *venc_name;
+  gchar *aenc_name;
+  gchar *ienc_name;
+  gchar *mux_name;
+  gchar *vconv_name;
+
+  GstCaps *vcaps;
+  GstCaps *acaps;
+  GstCaps *icaps;
+
+  gboolean auto_audio_convert;
+  gboolean auto_audio_resample;
+  gboolean auto_color_space;
+  gboolean block;
+  gboolean pause;
+  gboolean use_video_toggle;
+  gboolean use_venc_queue;
+  gboolean use_aenc_queue;
+
   GstElement *audio_queue;
-  GstElement *video_queue;  
-  GstElement *video_encode_queue;    
-  GstElement *audio_encode_queue;      
-  GstElement *image_queue;    
-  
+  GstElement *video_queue;
+  GstElement *video_encode_queue;
+  GstElement *audio_encode_queue;
+  GstElement *image_queue;
+
   GstElement *audio_encode;
   GstElement *video_encode;
-  GstElement *image_encode;  
+  GstElement *image_encode;
+
+  GstElement *vcapsfilter;
+  GstElement *acapsfilter;
+  GstElement *icapsfilter;
 
-  GstElement *vcapsfilter;  
-  GstElement *acapsfilter;    
-  GstElement *icapsfilter;      
-  
   GstElement *video_toggle;
-  GstElement *image_toggle;  
-  GstElement *color_space;  
-  GstElement *audio_conv;  
+  GstElement *image_toggle;
+  GstElement *color_space;
+  GstElement *audio_conv;
   GstElement *audio_sample;
-  
+
   GstElement *mux;
 
   /* pause/resume variables */
-  GstClockTime         paused_time;                    /* pipeline time when pausing */
-  GstClockTime         total_offset_time;              /* delayed time which is due to pause */
-  gulong               vsink_probeid;
-  gulong               vsink_hs_probeid;
-  gulong               asink_probeid;
-  gulong               veque_sig_id;
-  gulong               aeque_sig_id;  
+  GstClockTime paused_time;             /* pipeline time when pausing */
+  GstClockTime total_offset_time;       /* delayed time which is due to pause */
+  gulong vsink_probeid;
+  gulong vsink_hs_probeid;
+  gulong asink_probeid;
+  gulong veque_sig_id;
+  gulong aeque_sig_id;
 };
 
 struct _GstEncodeBinClass
diff --git a/evaspixmapsink/Makefile.am b/evaspixmapsink/Makefile.am
new file mode 100644 (file)
index 0000000..cd6588c
--- /dev/null
@@ -0,0 +1,15 @@
+plugin_LTLIBRARIES = libgstevaspixmapsink.la
+
+libgstevaspixmapsink_la_SOURCES = evaspixmapsink.c
+libgstevaspixmapsink_la_CFLAGS = $(GST_CFLAGS) $(X_CFLAGS) $(EFL_CFLAGS) $(MMTA_CFLAGS) \
+       $(XFIXES_CFLAGS) $(DRI2PROTO_CFLAGS) $(DRI2_CFLAGS) $(X11_CFLAGS) $(XDAMAGE_CFLAGS) $(XV_CFLAGS)
+libgstevaspixmapsink_la_LIBADD = \
+       $(GST_LIBS) -lgstvideo-$(GST_MAJORMINOR) -lgstinterfaces-$(GST_MAJORMINOR) \
+       $(X_LIBS) $(XVIDEO_LIBS) $(XSHM_LIBS) $(LIBM) \
+       $(EFL_LIBS) \
+       $(MMTA_LIBS) \
+       $(XFIXES_LIBS) $(DRI2PROTO_LIBS) $(DRI2_LIBS) $(X11_LIBS) $(XDAMAGE_LIBS) $(XV_LIBS)
+libgstevaspixmapsink_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
+libgstxvimagesink_la_LIBTOOLFLAGS = --tag=disable-static
+
+noinst_HEADERS = evaspixmapsink.h
diff --git a/evaspixmapsink/evaspixmapsink.c b/evaspixmapsink/evaspixmapsink.c
new file mode 100644 (file)
index 0000000..385e9b4
--- /dev/null
@@ -0,0 +1,3783 @@
+/*
+ * EvasPixmapSink
+ *
+ * Copyright (c) 2000 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Sangchul Lee <sc11.lee@samsung.com>
+ *
+ * This library is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the
+ * Free Software Foundation; either version 2.1 of the License, or (at your option)
+ * any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software Foundation, Inc., 51
+ * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+/* Our interfaces */
+#include <gst/interfaces/navigation.h>
+#include <gst/interfaces/colorbalance.h>
+#include <gst/interfaces/propertyprobe.h>
+/* Helper functions */
+#include <gst/video/video.h>
+
+/* Object header */
+#include "evaspixmapsink.h"
+
+#ifdef GST_EXT_XV_ENHANCEMENT
+/* Samsung extension headers */
+/* For xv extension header for buffer transfer (output) */
+#include "xv_types.h"
+
+/* headers for drm */
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <X11/Xmd.h>
+#include <dri2/dri2.h>
+#include <libdrm/drm.h>
+
+typedef enum {
+       BUF_SHARE_METHOD_PADDR = 0,
+       BUF_SHARE_METHOD_FD
+} buf_share_method_t;
+
+/* max channel count *********************************************************/
+#define SCMN_IMGB_MAX_PLANE         (4)
+
+/* image buffer definition ***************************************************
+
+    +------------------------------------------+ ---
+    |                                          |  ^
+    |     a[], p[]                             |  |
+    |     +---------------------------+ ---    |  |
+    |     |                           |  ^     |  |
+    |     |<---------- w[] ---------->|  |     |  |
+    |     |                           |  |     |  |
+    |     |                           |        |
+    |     |                           |  h[]   |  e[]
+    |     |                           |        |
+    |     |                           |  |     |  |
+    |     |                           |  |     |  |
+    |     |                           |  v     |  |
+    |     +---------------------------+ ---    |  |
+    |                                          |  v
+    +------------------------------------------+ ---
+
+    |<----------------- s[] ------------------>|
+*/
+
+typedef struct
+{
+       /* width of each image plane */
+       int      w[SCMN_IMGB_MAX_PLANE];
+       /* height of each image plane */
+       int      h[SCMN_IMGB_MAX_PLANE];
+       /* stride of each image plane */
+       int      s[SCMN_IMGB_MAX_PLANE];
+       /* elevation of each image plane */
+       int      e[SCMN_IMGB_MAX_PLANE];
+       /* user space address of each image plane */
+       void   * a[SCMN_IMGB_MAX_PLANE];
+       /* physical address of each image plane, if needs */
+       void   * p[SCMN_IMGB_MAX_PLANE];
+       /* color space type of image */
+       int      cs;
+       /* left postion, if needs */
+       int      x;
+       /* top position, if needs */
+       int      y;
+       /* to align memory */
+       int      __dummy2;
+       /* arbitrary data */
+       int      data[16];
+       /* dma buf fd */
+       int dma_buf_fd[SCMN_IMGB_MAX_PLANE];
+       /* buffer share method */
+       int buf_share_method;
+} SCMN_IMGB;
+#endif
+
+/* Debugging category */
+#include <gst/gstinfo.h>
+GST_DEBUG_CATEGORY_STATIC (gst_debug_evaspixmapsink);
+#define GST_CAT_DEFAULT gst_debug_evaspixmapsink
+GST_DEBUG_CATEGORY_STATIC (GST_CAT_PERFORMANCE);
+
+#ifdef GST_EXT_XV_ENHANCEMENT
+
+enum {
+    DEGREE_0,
+    DEGREE_90,
+    DEGREE_180,
+    DEGREE_270,
+    DEGREE_NUM,
+};
+
+enum {
+    DISP_GEO_METHOD_LETTER_BOX = 0,
+    DISP_GEO_METHOD_ORIGIN_SIZE,
+    DISP_GEO_METHOD_FULL_SCREEN,
+    DISP_GEO_METHOD_CROPPED_FULL_SCREEN,
+    DISP_GEO_METHOD_CUSTOM_ROI,
+    DISP_GEO_METHOD_NUM,
+};
+
+#define DEF_DISPLAY_GEOMETRY_METHOD DISP_GEO_METHOD_LETTER_BOX
+
+#define GST_TYPE_EVASPIXMAPSINK_DISPLAY_GEOMETRY_METHOD (gst_evaspixmapsink_display_geometry_method_get_type())
+
+static GType
+gst_evaspixmapsink_display_geometry_method_get_type(void)
+{
+       static GType evaspixmapsink_display_geometry_method_type = 0;
+       static const GEnumValue display_geometry_method_type[] = {
+               { 0, "Letter box", "LETTER_BOX"},
+               { 1, "Origin size", "ORIGIN_SIZE"},
+               { 2, "Full-screen", "FULL_SCREEN"},
+               { 3, "Cropped Full-screen", "CROPPED_FULL_SCREEN"},
+               { 4, "Explicitely described destination ROI", "CUSTOM_ROI"},
+               { 5, NULL, NULL},
+       };
+
+       if (!evaspixmapsink_display_geometry_method_type) {
+               evaspixmapsink_display_geometry_method_type = g_enum_register_static("GstEvasPixmapSinkDisplayGeometryMethodType", display_geometry_method_type);
+       }
+
+       return evaspixmapsink_display_geometry_method_type;
+}
+#endif /* GST_EXT_XV_ENHANCEMENT */
+
+typedef struct
+{
+  unsigned long flags;
+  unsigned long functions;
+  unsigned long decorations;
+  long input_mode;
+  unsigned long status;
+}
+MotifWmHints, MwmHints;
+
+#define MWM_HINTS_DECORATIONS   (1L << 1)
+
+static void gst_evaspixmapsink_reset (GstEvasPixmapSink *evaspixmapsink);
+static GstBufferClass *evaspixmap_buffer_parent_class = NULL;
+static void gst_evaspixmap_buffer_finalize (GstEvasPixmapBuffer *evaspixmapbuf);
+static void gst_evaspixmapsink_xcontext_clear (GstEvasPixmapSink *evaspixmapsink);
+static void gst_evaspixmapsink_xpixmap_destroy (GstEvasPixmapSink *evaspixmapsink, GstXPixmap *xpixmap);
+static void gst_evaspixmapsink_xpixmap_update_geometry (GstEvasPixmapSink *evaspixmapsink);
+static gboolean gst_evaspixmap_buffer_put (GstEvasPixmapSink *evaspixmapsink, GstEvasPixmapBuffer *evaspixmapbuf);
+static gboolean gst_evaspixmapsink_xpixmap_link (GstEvasPixmapSink *evaspixmapsink);
+static void gst_evaspixmapsink_xpixmap_clear (GstEvasPixmapSink *evaspixmapsink, GstXPixmap *xpixmap);
+static gint gst_evaspixmapsink_get_format_from_caps (GstEvasPixmapSink *evaspixmapsink, GstCaps *caps);
+static void drm_close_gem(GstEvasPixmapSink *evaspixmapsink, unsigned int gem_handle);
+
+/* Default template - initiated with class struct to allow gst-register to work
+   without X running */
+static GstStaticPadTemplate gst_evaspixmapsink_sink_template_factory =
+    GST_STATIC_PAD_TEMPLATE ("sink",
+    GST_PAD_SINK,
+    GST_PAD_ALWAYS,
+    GST_STATIC_CAPS ("video/x-raw-rgb, "
+        "framerate = (fraction) [ 0, MAX ], "
+        "width = (int) [ 1, MAX ], "
+        "height = (int) [ 1, MAX ]; "
+        "video/x-raw-yuv, "
+        "framerate = (fraction) [ 0, MAX ], "
+        "width = (int) [ 1, MAX ], " "height = (int) [ 1, MAX ]")
+    );
+
+enum
+{
+  PROP_0,
+  PROP_CONTRAST,
+  PROP_BRIGHTNESS,
+  PROP_HUE,
+  PROP_SATURATION,
+  PROP_DISPLAY,
+  PROP_SYNCHRONOUS,
+  PROP_PIXEL_ASPECT_RATIO,
+  PROP_FORCE_ASPECT_RATIO,
+  PROP_DEVICE,
+  PROP_DEVICE_NAME,
+  PROP_DOUBLE_BUFFER,
+  PROP_AUTOPAINT_COLORKEY,
+  PROP_COLORKEY,
+  PROP_PIXMAP_WIDTH,
+  PROP_PIXMAP_HEIGHT,
+#ifdef GST_EXT_XV_ENHANCEMENT
+  PROP_DISPLAY_GEOMETRY_METHOD,
+  PROP_ZOOM,
+  PROP_DST_ROI_X,
+  PROP_DST_ROI_Y,
+  PROP_DST_ROI_W,
+  PROP_DST_ROI_H,
+  PROP_STOP_VIDEO,
+#endif
+  PROP_EVAS_OBJECT,
+  PROP_VISIBLE,
+  PROP_ORIGIN_SIZE,
+};
+
+static GstVideoSinkClass *parent_class = NULL;
+
+/* ============================================================= */
+/*                                                               */
+/*                       Private Methods                         */
+/*                                                               */
+/* ============================================================= */
+
+/* evaspixmap buffers */
+
+#define GST_TYPE_EVASPIXMAP_BUFFER (gst_evaspixmap_buffer_get_type())
+
+#define GST_IS_EVASPIXMAP_BUFFER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_EVASPIXMAP_BUFFER))
+#define GST_EVASPIXMAP_BUFFER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_EVASPIXMAP_BUFFER, GstEvasPixmapBuffer))
+
+static void
+ecore_pipe_callback_handler (void *data, void *buffer, unsigned int nbyte)
+{
+       GstEvasPixmapSink *evaspixmapsink = (GstEvasPixmapSink*)data;
+       GST_DEBUG_OBJECT (evaspixmapsink,"[START]");
+
+       if (!data ) {
+               GST_WARNING_OBJECT (evaspixmapsink,"data is NULL..");
+               return;
+       }
+       if (!evaspixmapsink->eo) {
+               GST_WARNING_OBJECT (evaspixmapsink,"evas object is NULL..");
+               return;
+       }
+
+       /* mapping evas object with xpixmap */
+       if (evaspixmapsink->do_link) {
+               GST_DEBUG_OBJECT (evaspixmapsink,"do link");
+               if (evaspixmapsink->xpixmap->pixmap) {
+                       Evas_Native_Surface surf;
+                       surf.version = EVAS_NATIVE_SURFACE_VERSION;
+                       surf.type = EVAS_NATIVE_SURFACE_X11;
+                       surf.data.x11.visual = ecore_x_default_visual_get(ecore_x_display_get(), ecore_x_default_screen_get());
+                       surf.data.x11.pixmap = evaspixmapsink->xpixmap->pixmap;
+                       __ta__("evaspixmapsink _native_surface_set", evas_object_image_native_surface_set(evaspixmapsink->eo, &surf); );
+                       evaspixmapsink->do_link = FALSE;
+               } else {
+                       GST_WARNING_OBJECT (evaspixmapsink,"pixmap is NULL..");
+                       return;
+               }
+       } else {
+               GST_DEBUG_OBJECT (evaspixmapsink,"update");
+               /* update evas image object size */
+               if (evaspixmapsink->use_origin_size) {
+                       evas_object_geometry_get(evaspixmapsink->eo, NULL, NULL, &evaspixmapsink->w, &evaspixmapsink->h);
+               }
+               MMTA_ACUM_ITEM_BEGIN("evaspixmapsink evas_object_image update", FALSE);
+               evas_object_image_pixels_dirty_set (evaspixmapsink->eo, 1);
+               evas_object_image_fill_set(evaspixmapsink->eo, 0, 0, evaspixmapsink->w, evaspixmapsink->h);
+               evas_object_image_data_update_add(evaspixmapsink->eo, 0, 0, evaspixmapsink->w, evaspixmapsink->h);
+               MMTA_ACUM_ITEM_END("evaspixmapsink evas_object_image update", FALSE);
+       }
+
+       GST_DEBUG_OBJECT (evaspixmapsink,"[END]");
+}
+
+static void
+evas_callback_resize_event (void *data, Evas *e, Evas_Object *obj, void *event_info)
+{
+       int w = 0;
+       int h = 0;
+       float former_ratio = 0;
+       float ratio = 0;
+       float abs_margin = 0;
+
+       GstEvasPixmapSink *evaspixmapsink = (GstEvasPixmapSink *)data;
+       GST_DEBUG_OBJECT (evaspixmapsink,"[START]");
+
+       evas_object_geometry_get(evaspixmapsink->eo, NULL, NULL, &w, &h);
+       GST_DEBUG_OBJECT (evaspixmapsink,"resized : w(%d), h(%d)", w, h);
+       if (!evaspixmapsink->use_origin_size &&
+                       (evaspixmapsink->w != w || evaspixmapsink->h != h)) {
+               former_ratio = (float)evaspixmapsink->w / evaspixmapsink->h;
+               ratio = (float)w / h;
+               evaspixmapsink->w = w;
+               evaspixmapsink->h = h;
+
+#ifdef COMPARE_RATIO
+               GST_DEBUG_OBJECT (evaspixmapsink,"resized : ratio(%.3f=>%.3f)", former_ratio, ratio);
+               if ( former_ratio >= ratio ) {
+                       abs_margin = former_ratio - ratio;
+               } else {
+                       abs_margin = ratio - former_ratio;
+               }
+               /* re-link_pixmap can only be set when ratio is changed */
+               if ( abs_margin >= MARGIN_OF_ERROR ) {
+#endif
+                       if (!gst_evaspixmapsink_xpixmap_link(evaspixmapsink)) {
+                               GST_ERROR_OBJECT (evaspixmapsink,"link evas image object with pixmap failed...");
+                               return;
+                       }
+#ifdef COMPARE_RATIO
+               }
+#endif
+       }
+
+       gst_evaspixmap_buffer_put (evaspixmapsink, evaspixmapsink->evas_pixmap_buf);
+
+       GST_DEBUG_OBJECT (evaspixmapsink,"[END]");
+}
+
+static inline gboolean
+is_evas_image_object (Evas_Object *obj)
+{
+       const char *type;
+       if (!obj) {
+               return FALSE;
+       }
+       type = evas_object_type_get (obj);
+       if (!type) {
+               return FALSE;
+       }
+       if (strcmp (type, "image") == 0) {
+               return TRUE;
+       }
+       return FALSE;
+}
+
+static void
+evas_callback_del_event (void *data, Evas *e, Evas_Object *obj, void *event_info)
+{
+       GstEvasPixmapSink *evaspixmapsink = data;
+       if (!evaspixmapsink) {
+               GST_WARNING ("evaspixmapsink is NULL..");
+               return;
+       }
+       GST_DEBUG_OBJECT (evaspixmapsink,"[START]");
+
+       evas_object_event_callback_del(evaspixmapsink->eo, EVAS_CALLBACK_RESIZE, evas_callback_resize_event);
+       if (evaspixmapsink->eo) {
+               evas_object_image_native_surface_set(evaspixmapsink->eo, NULL);
+               evaspixmapsink->eo = NULL;
+       }
+
+       GST_DEBUG_OBJECT (evaspixmapsink,"[END]");
+}
+
+/* X11 stuff */
+static gboolean error_caught = FALSE;
+
+static int
+gst_evaspixmapsink_handle_xerror (Display * display, XErrorEvent * xevent)
+{
+  char error_msg[1024];
+
+  XGetErrorText (display, xevent->error_code, error_msg, 1024);
+  GST_DEBUG ("evaspixmapsink triggered an XError. error: %s", error_msg);
+  error_caught = TRUE;
+  return 0;
+}
+
+#ifdef HAVE_XSHM
+/* This function checks that it is actually really possible to create an image
+   using XShm */
+static gboolean
+gst_evaspixmapsink_check_xshm_calls (GstXContext * xcontext)
+{
+  XvImage *xvimage;
+  XShmSegmentInfo SHMInfo;
+  gint size;
+  int (*handler) (Display *, XErrorEvent *);
+  gboolean result = FALSE;
+  gboolean did_attach = FALSE;
+
+  g_return_val_if_fail (xcontext != NULL, FALSE);
+
+  /* Sync to ensure any older errors are already processed */
+  XSync (xcontext->disp, FALSE);
+
+  /* Set defaults so we don't free these later unnecessarily */
+  SHMInfo.shmaddr = ((void *) -1);
+  SHMInfo.shmid = -1;
+
+  /* Setting an error handler to catch failure */
+  error_caught = FALSE;
+  handler = XSetErrorHandler (gst_evaspixmapsink_handle_xerror);
+
+  /* Trying to create a 1x1 picture */
+  GST_DEBUG ("XvShmCreateImage of 1x1");
+  xvimage = XvShmCreateImage (xcontext->disp, xcontext->xv_port_id,
+      xcontext->im_format, NULL, 1, 1, &SHMInfo);
+
+  /* Might cause an error, sync to ensure it is noticed */
+  XSync (xcontext->disp, FALSE);
+  if (!xvimage || error_caught) {
+    GST_WARNING ("could not XvShmCreateImage a 1x1 image");
+    goto beach;
+  }
+  size = xvimage->data_size;
+
+  SHMInfo.shmid = shmget (IPC_PRIVATE, size, IPC_CREAT | 0777);
+  if (SHMInfo.shmid == -1) {
+    GST_WARNING ("could not get shared memory of %d bytes", size);
+    goto beach;
+  }
+
+  SHMInfo.shmaddr = shmat (SHMInfo.shmid, NULL, 0);
+  if (SHMInfo.shmaddr == ((void *) -1)) {
+    GST_WARNING ("Failed to shmat: %s", g_strerror (errno));
+    /* Clean up the shared memory segment */
+    shmctl (SHMInfo.shmid, IPC_RMID, NULL);
+    goto beach;
+  }
+
+  xvimage->data = SHMInfo.shmaddr;
+  SHMInfo.readOnly = FALSE;
+
+  if (XShmAttach (xcontext->disp, &SHMInfo) == 0) {
+    GST_WARNING ("Failed to XShmAttach");
+    /* Clean up the shared memory segment */
+    shmctl (SHMInfo.shmid, IPC_RMID, NULL);
+    goto beach;
+  }
+
+  /* Sync to ensure we see any errors we caused */
+  XSync (xcontext->disp, FALSE);
+
+  /* Delete the shared memory segment as soon as everyone is attached.
+   * This way, it will be deleted as soon as we detach later, and not
+   * leaked if we crash. */
+  shmctl (SHMInfo.shmid, IPC_RMID, NULL);
+
+  if (!error_caught) {
+    GST_DEBUG ("XServer ShmAttached to 0x%x, id 0x%lx", SHMInfo.shmid,
+        SHMInfo.shmseg);
+
+    did_attach = TRUE;
+    /* store whether we succeeded in result */
+    result = TRUE;
+  } else {
+    GST_WARNING ("MIT-SHM extension check failed at XShmAttach. "
+        "Not using shared memory.");
+  }
+
+beach:
+  /* Sync to ensure we swallow any errors we caused and reset error_caught */
+  XSync (xcontext->disp, FALSE);
+
+  error_caught = FALSE;
+  XSetErrorHandler (handler);
+
+  if (did_attach) {
+    GST_DEBUG ("XServer ShmDetaching from 0x%x id 0x%lx",
+        SHMInfo.shmid, SHMInfo.shmseg);
+    XShmDetach (xcontext->disp, &SHMInfo);
+    XSync (xcontext->disp, FALSE);
+  }
+  if (SHMInfo.shmaddr != ((void *) -1))
+    shmdt (SHMInfo.shmaddr);
+  if (xvimage)
+    XFree (xvimage);
+  return result;
+}
+#endif /* HAVE_XSHM */
+
+/* This function destroys a GstEvasPixmap handling XShm availability */
+static void
+gst_evaspixmap_buffer_destroy (GstEvasPixmapBuffer *evaspixmapbuf)
+{
+       GstEvasPixmapSink *evaspixmapsink;
+
+       GST_DEBUG_OBJECT (evaspixmapsink,"Destroying buffer");
+
+       evaspixmapsink = evaspixmapbuf->evaspixmapsink;
+       if (G_UNLIKELY (evaspixmapsink == NULL)) {
+               goto no_sink;
+       }
+
+       g_return_if_fail (GST_IS_EVASPIXMAPSINK (evaspixmapsink));
+
+       GST_OBJECT_LOCK (evaspixmapsink);
+
+       /* We might have some buffers destroyed after changing state to NULL */
+       if (evaspixmapsink->xcontext == NULL) {
+               GST_DEBUG_OBJECT (evaspixmapsink,"Destroying XvImage after Xcontext");
+#ifdef HAVE_XSHM
+               /* Need to free the shared memory segment even if the x context
+               * was already cleaned up */
+               if (evaspixmapbuf->SHMInfo.shmaddr != ((void *) -1)) {
+                       shmdt (evaspixmapbuf->SHMInfo.shmaddr);
+               }
+#endif
+               goto beach;
+       }
+       g_mutex_lock (evaspixmapsink->x_lock);
+
+#ifdef HAVE_XSHM
+       if (evaspixmapsink->xcontext->use_xshm) {
+               if (evaspixmapbuf->SHMInfo.shmaddr != ((void *) -1)) {
+                       GST_DEBUG_OBJECT (evaspixmapsink,"XServer ShmDetaching from 0x%x id 0x%lx", evaspixmapbuf->SHMInfo.shmid, evaspixmapbuf->SHMInfo.shmseg);
+                       XShmDetach (evaspixmapsink->xcontext->disp, &evaspixmapbuf->SHMInfo);
+                       XSync (evaspixmapsink->xcontext->disp, FALSE);
+                       shmdt (evaspixmapbuf->SHMInfo.shmaddr);
+               }
+               if (evaspixmapbuf->xvimage)
+               XFree (evaspixmapbuf->xvimage);
+       } else
+#endif /* HAVE_XSHM */
+       {
+               if (evaspixmapbuf->xvimage) {
+                       if (evaspixmapbuf->xvimage->data) {
+                               g_free (evaspixmapbuf->xvimage->data);
+                       }
+                       XFree (evaspixmapbuf->xvimage);
+               }
+       }
+
+       XSync (evaspixmapsink->xcontext->disp, FALSE);
+
+       g_mutex_unlock (evaspixmapsink->x_lock);
+
+beach:
+       GST_OBJECT_UNLOCK (evaspixmapsink);
+       evaspixmapbuf->evaspixmapsink = NULL;
+       gst_object_unref (evaspixmapsink);
+
+       GST_MINI_OBJECT_CLASS (evaspixmap_buffer_parent_class)->finalize (GST_MINI_OBJECT(evaspixmapbuf));
+
+       return;
+
+       no_sink:
+       {
+               GST_WARNING_OBJECT (evaspixmapsink,"no sink found");
+               return;
+       }
+}
+
+static void
+gst_evaspixmap_buffer_finalize (GstEvasPixmapBuffer *evaspixmapbuf)
+{
+       GstEvasPixmapSink *evaspixmapsink;
+
+       evaspixmapsink = evaspixmapbuf->evaspixmapsink;
+       if (G_UNLIKELY (evaspixmapsink == NULL)) {
+               GST_WARNING_OBJECT (evaspixmapsink,"no sink found");
+               return;
+       }
+       g_return_if_fail (GST_IS_EVASPIXMAPSINK (evaspixmapsink));
+
+        /* If our geometry changed we can't reuse that image. */
+       GST_LOG_OBJECT (evaspixmapsink,"destroy image as sink is shutting down");
+       gst_evaspixmap_buffer_destroy (evaspixmapbuf);
+}
+
+static void
+gst_evaspixmap_buffer_free (GstEvasPixmapBuffer *evaspixmapbuf)
+{
+  /* make sure it is not recycled */
+  evaspixmapbuf->width = -1;
+  evaspixmapbuf->height = -1;
+  gst_buffer_unref (GST_BUFFER (evaspixmapbuf));
+}
+
+static void
+gst_evaspixmap_buffer_init (GstEvasPixmapBuffer *evaspixmapbuf, gpointer g_class)
+{
+#ifdef HAVE_XSHM
+  evaspixmapbuf->SHMInfo.shmaddr = ((void *) -1);
+  evaspixmapbuf->SHMInfo.shmid = -1;
+#endif
+}
+
+static void
+gst_evaspixmap_buffer_class_init (gpointer g_class, gpointer class_data)
+{
+  GstMiniObjectClass *mini_object_class = GST_MINI_OBJECT_CLASS (g_class);
+
+  evaspixmap_buffer_parent_class = g_type_class_peek_parent (g_class);
+
+  mini_object_class->finalize = (GstMiniObjectFinalizeFunction) gst_evaspixmap_buffer_finalize;
+}
+
+static GType
+gst_evaspixmap_buffer_get_type (void)
+{
+  static GType _gst_evaspixmap_buffer_type;
+
+  if (G_UNLIKELY (_gst_evaspixmap_buffer_type == 0)) {
+    static const GTypeInfo evaspixmap_buffer_info = {
+      sizeof (GstBufferClass),
+      NULL,
+      NULL,
+      gst_evaspixmap_buffer_class_init,
+      NULL,
+      NULL,
+      sizeof (GstEvasPixmapBuffer),
+      0,
+      (GInstanceInitFunc) gst_evaspixmap_buffer_init,
+      NULL
+    };
+    _gst_evaspixmap_buffer_type = g_type_register_static (GST_TYPE_BUFFER,
+        "GstEvasPixmapBuffer", &evaspixmap_buffer_info, 0);
+  }
+  return _gst_evaspixmap_buffer_type;
+}
+
+/* This function handles GstEvasPixmapBuffer creation depending on XShm availability */
+static GstEvasPixmapBuffer*
+gst_evaspixmap_buffer_new (GstEvasPixmapSink *evaspixmapsink, GstCaps *caps)
+{
+       GstEvasPixmapBuffer *evaspixmapbuf = NULL;
+       GstStructure *structure = NULL;
+       gboolean succeeded = FALSE;
+       int (*handler) (Display *, XErrorEvent *);
+
+       g_return_val_if_fail (GST_IS_EVASPIXMAPSINK (evaspixmapsink), NULL);
+
+       if (caps == NULL) {
+               return NULL;
+       }
+
+       evaspixmapbuf = (GstEvasPixmapBuffer*) gst_mini_object_new (GST_TYPE_EVASPIXMAP_BUFFER);
+       GST_DEBUG_OBJECT (evaspixmapsink,"Creating new EvasPixmapBuffer");
+
+       structure = gst_caps_get_structure (caps, 0);
+
+       if (!gst_structure_get_int (structure, "width", &evaspixmapbuf->width) || !gst_structure_get_int (structure, "height", &evaspixmapbuf->height)) {
+               GST_WARNING_OBJECT (evaspixmapsink,"failed getting geometry from caps %" GST_PTR_FORMAT, caps);
+       }
+
+       GST_LOG_OBJECT (evaspixmapsink,"creating %dx%d", evaspixmapbuf->width, evaspixmapbuf->height);
+#ifdef GST_EXT_XV_ENHANCEMENT
+       GST_LOG_OBJECT (evaspixmapsink,"aligned size %dx%d", evaspixmapsink->aligned_width, evaspixmapsink->aligned_height);
+       if (evaspixmapsink->aligned_width == 0 || evaspixmapsink->aligned_height == 0) {
+               GST_INFO_OBJECT (evaspixmapsink,"aligned size is zero. set size of caps.");
+               evaspixmapsink->aligned_width = evaspixmapbuf->width;
+               evaspixmapsink->aligned_height = evaspixmapbuf->height;
+       }
+#endif
+
+       evaspixmapbuf->im_format = gst_evaspixmapsink_get_format_from_caps (evaspixmapsink, caps);
+       if (evaspixmapbuf->im_format == -1) {
+               GST_WARNING_OBJECT (evaspixmapsink,"failed to get format from caps %"GST_PTR_FORMAT, caps);
+               GST_ELEMENT_ERROR (evaspixmapsink, RESOURCE, WRITE,("Failed to create output image buffer of %dx%d pixels",
+                                  evaspixmapbuf->width, evaspixmapbuf->height), ("Invalid input caps"));
+               goto beach_unlocked;
+       }
+       evaspixmapbuf->evaspixmapsink = gst_object_ref (evaspixmapsink);
+
+       g_mutex_lock (evaspixmapsink->x_lock);
+
+       /* Setting an error handler to catch failure */
+       error_caught = FALSE;
+       handler = XSetErrorHandler (gst_evaspixmapsink_handle_xerror);
+
+#ifdef HAVE_XSHM
+       if (evaspixmapsink->xcontext->use_xshm) {
+               int expected_size;
+               evaspixmapbuf->xvimage = XvShmCreateImage (evaspixmapsink->xcontext->disp, evaspixmapsink->xcontext->xv_port_id, evaspixmapbuf->im_format, NULL,
+#ifdef GST_EXT_XV_ENHANCEMENT
+               evaspixmapsink->aligned_width, evaspixmapsink->aligned_height, &evaspixmapbuf->SHMInfo);
+               if(!evaspixmapbuf->xvimage) {
+                       GST_ERROR_OBJECT (evaspixmapsink,"XvShmCreateImage() failed");
+               }
+#else
+               evaspixmapbuf->width, evaspixmapbuf->height, &evaspixmapbuf->SHMInfo);
+#endif
+               if (!evaspixmapbuf->xvimage || error_caught) {
+                       if (error_caught) {
+                               GST_ERROR_OBJECT (evaspixmapsink,"error_caught!");
+                       }
+                       g_mutex_unlock (evaspixmapsink->x_lock);
+                       /* Reset error handler */
+                       error_caught = FALSE;
+                       XSetErrorHandler (handler);
+                       /* Push an error */
+                       GST_ELEMENT_ERROR (evaspixmapsink, RESOURCE, WRITE,("Failed to create output image buffer of %dx%d pixels",evaspixmapbuf->width,
+                                  evaspixmapbuf->height),("could not XvShmCreateImage a %dx%d image",evaspixmapbuf->width, evaspixmapbuf->height));
+                       goto beach_unlocked;
+               }
+
+               /* we have to use the returned data_size for our shm size */
+               evaspixmapbuf->size = evaspixmapbuf->xvimage->data_size;
+               GST_LOG_OBJECT (evaspixmapsink,"XShm image size is %" G_GSIZE_FORMAT, evaspixmapbuf->size);
+
+               /* calculate the expected size.  This is only for sanity checking the
+               * number we get from X. */
+               switch (evaspixmapbuf->im_format) {
+               case GST_MAKE_FOURCC ('I', '4', '2', '0'):
+               case GST_MAKE_FOURCC ('Y', 'V', '1', '2'):
+               {
+                       gint pitches[3];
+                       gint offsets[3];
+                       guint plane;
+
+                       offsets[0] = 0;
+                       pitches[0] = GST_ROUND_UP_4 (evaspixmapbuf->width);
+                       offsets[1] = offsets[0] + pitches[0] * GST_ROUND_UP_2 (evaspixmapbuf->height);
+                       pitches[1] = GST_ROUND_UP_8 (evaspixmapbuf->width) / 2;
+                       offsets[2] =
+                       offsets[1] + pitches[1] * GST_ROUND_UP_2 (evaspixmapbuf->height) / 2;
+                       pitches[2] = GST_ROUND_UP_8 (pitches[0]) / 2;
+
+                       expected_size = offsets[2] + pitches[2] * GST_ROUND_UP_2 (evaspixmapbuf->height) / 2;
+
+                       for (plane = 0; plane < evaspixmapbuf->xvimage->num_planes; plane++) {
+                               GST_DEBUG_OBJECT (evaspixmapsink,"Plane %u has a expected pitch of %d bytes, " "offset of %d",
+                                               plane, pitches[plane], offsets[plane]);
+                       }
+                       break;
+               }
+               case GST_MAKE_FOURCC ('Y', 'U', 'Y', '2'):
+               case GST_MAKE_FOURCC ('U', 'Y', 'V', 'Y'):
+                       expected_size = evaspixmapbuf->height * GST_ROUND_UP_4 (evaspixmapbuf->width * 2);
+                       break;
+
+               #ifdef GST_EXT_XV_ENHANCEMENT
+               case GST_MAKE_FOURCC ('S', 'T', '1', '2'):
+               case GST_MAKE_FOURCC ('S', 'N', '1', '2'):
+               case GST_MAKE_FOURCC ('S', 'U', 'Y', 'V'):
+               case GST_MAKE_FOURCC ('S', 'U', 'Y', '2'):
+               case GST_MAKE_FOURCC ('S', '4', '2', '0'):
+               case GST_MAKE_FOURCC ('S', 'Y', 'V', 'Y'):
+                       expected_size = sizeof(SCMN_IMGB);
+                       break;
+               #endif
+               default:
+                       expected_size = 0;
+                       break;
+               }
+               if (expected_size != 0 && evaspixmapbuf->size != expected_size) {
+                       GST_WARNING_OBJECT (evaspixmapsink,"unexpected XShm image size (got %" G_GSIZE_FORMAT ", expected %d)", evaspixmapbuf->size, expected_size);
+               }
+
+               /* Be verbose about our XvImage stride */
+               {
+                       guint plane;
+                       for (plane = 0; plane < evaspixmapbuf->xvimage->num_planes; plane++) {
+                               GST_DEBUG_OBJECT (evaspixmapsink,"Plane %u has a pitch of %d bytes, ""offset of %d", plane,
+                                               evaspixmapbuf->xvimage->pitches[plane], evaspixmapbuf->xvimage->offsets[plane]);
+                       }
+               }
+
+               evaspixmapbuf->SHMInfo.shmid = shmget (IPC_PRIVATE, evaspixmapbuf->size,IPC_CREAT | 0777);
+               if (evaspixmapbuf->SHMInfo.shmid == -1) {
+                       g_mutex_unlock (evaspixmapsink->x_lock);
+                       GST_ELEMENT_ERROR (evaspixmapsink, RESOURCE, WRITE,
+                               ("Failed to create output image buffer of %dx%d pixels", evaspixmapbuf->width, evaspixmapbuf->height),
+                               ("could not get shared memory of %" G_GSIZE_FORMAT " bytes",evaspixmapbuf->size));
+                       goto beach_unlocked;
+               }
+
+               evaspixmapbuf->SHMInfo.shmaddr = shmat (evaspixmapbuf->SHMInfo.shmid, NULL, 0);
+               if (evaspixmapbuf->SHMInfo.shmaddr == ((void *) -1)) {
+                       g_mutex_unlock (evaspixmapsink->x_lock);
+                       GST_ELEMENT_ERROR (evaspixmapsink, RESOURCE, WRITE,
+                               ("Failed to create output image buffer of %dx%d pixels",
+                               evaspixmapbuf->width, evaspixmapbuf->height),
+                               ("Failed to shmat: %s", g_strerror (errno)));
+                       /* Clean up the shared memory segment */
+                       shmctl (evaspixmapbuf->SHMInfo.shmid, IPC_RMID, NULL);
+                       goto beach_unlocked;
+               }
+
+               evaspixmapbuf->xvimage->data = evaspixmapbuf->SHMInfo.shmaddr;
+               evaspixmapbuf->SHMInfo.readOnly = FALSE;
+
+               if (XShmAttach (evaspixmapsink->xcontext->disp, &evaspixmapbuf->SHMInfo) == 0) {
+               /* Clean up the shared memory segment */
+               shmctl (evaspixmapbuf->SHMInfo.shmid, IPC_RMID, NULL);
+
+               g_mutex_unlock (evaspixmapsink->x_lock);
+               GST_ELEMENT_ERROR (evaspixmapsink, RESOURCE, WRITE,
+                       ("Failed to create output image buffer of %dx%d pixels",
+                       evaspixmapbuf->width, evaspixmapbuf->height), ("Failed to XShmAttach"));
+               goto beach_unlocked;
+               }
+
+               XSync (evaspixmapsink->xcontext->disp, FALSE);
+
+               /* Delete the shared memory segment as soon as we everyone is attached.
+               * This way, it will be deleted as soon as we detach later, and not
+               * leaked if we crash. */
+               shmctl (evaspixmapbuf->SHMInfo.shmid, IPC_RMID, NULL);
+
+               GST_DEBUG_OBJECT (evaspixmapsink,"XServer ShmAttached to 0x%x, id 0x%lx", evaspixmapbuf->SHMInfo.shmid, evaspixmapbuf->SHMInfo.shmseg);
+       } else
+#endif /* HAVE_XSHM */
+       {
+               evaspixmapbuf->xvimage = XvCreateImage (evaspixmapsink->xcontext->disp, evaspixmapsink->xcontext->xv_port_id,
+#ifdef GST_EXT_XV_ENHANCEMENT
+               evaspixmapbuf->im_format, NULL, evaspixmapsink->aligned_width, evaspixmapsink->aligned_height);
+#else
+               evaspixmapbuf->im_format, NULL, evaspixmapbuf->width, evaspixmapbuf->height);
+#endif
+               if (!evaspixmapbuf->xvimage || error_caught) {
+                       g_mutex_unlock (evaspixmapsink->x_lock);
+                       /* Reset error handler */
+                       error_caught = FALSE;
+                       XSetErrorHandler (handler);
+                       /* Push an error */
+                       GST_ELEMENT_ERROR (evaspixmapsink, RESOURCE, WRITE,
+                               ("Failed to create outputimage buffer of %dx%d pixels",
+                               evaspixmapbuf->width, evaspixmapbuf->height),
+                               ("could not XvCreateImage a %dx%d image",
+                               evaspixmapbuf->width, evaspixmapbuf->height));
+                       goto beach_unlocked;
+               }
+
+               /* we have to use the returned data_size for our image size */
+               evaspixmapbuf->size = evaspixmapbuf->xvimage->data_size;
+               evaspixmapbuf->xvimage->data = g_malloc (evaspixmapbuf->size);
+
+               XSync (evaspixmapsink->xcontext->disp, FALSE);
+       }
+
+       /* Reset error handler */
+       error_caught = FALSE;
+       XSetErrorHandler (handler);
+
+       succeeded = TRUE;
+
+       GST_BUFFER_DATA (evaspixmapbuf) = (guchar *) evaspixmapbuf->xvimage->data;
+       GST_BUFFER_SIZE (evaspixmapbuf) = evaspixmapbuf->size;
+
+       g_mutex_unlock (evaspixmapsink->x_lock);
+
+beach_unlocked:
+       if (!succeeded) {
+               gst_evaspixmap_buffer_free (evaspixmapbuf);
+               evaspixmapbuf = NULL;
+       }
+
+       return evaspixmapbuf;
+}
+
+/* This function puts a GstEvasPixmapBuffer on a GstEvasPixmapSink's pixmap. Returns FALSE
+ * if no pixmap was available  */
+static gboolean
+gst_evaspixmap_buffer_put (GstEvasPixmapSink *evaspixmapsink, GstEvasPixmapBuffer *evaspixmapbuf)
+{
+       GstVideoRectangle result;
+
+#ifdef GST_EXT_XV_ENHANCEMENT
+       GstVideoRectangle src_origin = { 0, 0, 0, 0};
+       GstVideoRectangle src_input  = { 0, 0, 0, 0};
+       GstVideoRectangle src = { 0, 0, 0, 0};
+       GstVideoRectangle dst = { 0, 0, 0, 0};
+       int rotate = 0;
+       int ret = 0;
+#endif
+
+       MMTA_ACUM_ITEM_BEGIN("evaspixmapsink evaspixmap_buffer_put", FALSE);
+
+       /* We take the flow_lock. If expose is in there we don't want to run
+       concurrently from the data flow thread */
+       g_mutex_lock (evaspixmapsink->flow_lock);
+
+       if (G_UNLIKELY (evaspixmapsink->xpixmap == NULL)) {
+               GST_WARNING_OBJECT (evaspixmapsink, "xpixmap is NULL. Skip buffer_put." );
+               g_mutex_unlock(evaspixmapsink->flow_lock);
+               return FALSE;
+       }
+       if (evaspixmapsink->visible == FALSE) {
+               GST_WARNING_OBJECT (evaspixmapsink, "visible is FALSE. Skip buffer_put." );
+               g_mutex_unlock(evaspixmapsink->flow_lock);
+               return TRUE;
+       }
+       if (!evaspixmapbuf) {
+               GST_WARNING_OBJECT (evaspixmapsink, "evaspixmapbuf is NULL. Skip buffer_put." );
+               g_mutex_unlock(evaspixmapsink->flow_lock);
+               return TRUE;
+       }
+
+#ifdef GST_EXT_XV_ENHANCEMENT
+       gst_evaspixmapsink_xpixmap_update_geometry( evaspixmapsink );
+
+       src.x = src.y = 0;
+       src_origin.x = src_origin.y = src_input.x = src_input.y = 0;
+       src_input.w = src_origin.w = evaspixmapsink->video_width;
+       src_input.h = src_origin.h = evaspixmapsink->video_height;
+       src.w = src_origin.w;
+       src.h = src_origin.h;
+
+       dst.w = evaspixmapsink->render_rect.w; /* pixmap width */
+       dst.h = evaspixmapsink->render_rect.h; /* pixmap heighy */
+
+       if (!evaspixmapsink->use_origin_size) {
+               switch (evaspixmapsink->display_geometry_method) {
+               case DISP_GEO_METHOD_LETTER_BOX:
+                       gst_video_sink_center_rect (src, dst, &result, TRUE);
+                       result.x += evaspixmapsink->render_rect.x;
+                       result.y += evaspixmapsink->render_rect.y;
+                       GST_DEBUG_OBJECT (evaspixmapsink, "GEO_METHOD : letter box");
+                       break;
+               case DISP_GEO_METHOD_ORIGIN_SIZE:
+                       gst_video_sink_center_rect (src, dst, &result, FALSE);
+                       gst_video_sink_center_rect (dst, src, &src_input, FALSE);
+                       GST_DEBUG_OBJECT (evaspixmapsink, "GEO_METHOD : origin size");
+                       break;
+               case DISP_GEO_METHOD_CROPPED_FULL_SCREEN:
+                       GST_DEBUG_OBJECT (evaspixmapsink, "GEO_METHOD : cropped full screen");
+                       gst_video_sink_center_rect(dst, src, &src_input, TRUE);
+                       result.x = result.y = 0;
+                       result.w = dst.w;
+                       result.h = dst.h;
+                       break;
+               case DISP_GEO_METHOD_FULL_SCREEN:
+                       result.x = result.y = 0;
+                       result.w = evaspixmapsink->xpixmap->width;
+                       result.h = evaspixmapsink->xpixmap->height;
+                       GST_DEBUG_OBJECT (evaspixmapsink, "GEO_METHOD : full screen");
+                       break;
+               case DISP_GEO_METHOD_CUSTOM_ROI:
+                       result.x = evaspixmapsink->dst_roi.x;
+                       result.y = evaspixmapsink->dst_roi.y;
+                       result.w = evaspixmapsink->dst_roi.w;
+                       result.h = evaspixmapsink->dst_roi.h;
+                       GST_DEBUG_OBJECT (evaspixmapsink, "GEO_METHOD : custom roi");
+                       break;
+               default:
+                       break;
+               }
+               GST_DEBUG_OBJECT (evaspixmapsink, "GEO_METHOD : src(%dx%d), dst(%dx%d), result(%dx%d), result_x(%d), result_y(%d)",
+                               src.w,src.h,dst.w,dst.h,result.w,result.h,result.x,result.y);
+       } else {
+               result.x = result.y = 0;
+               result.w = evaspixmapsink->xpixmap->width;
+               result.h = evaspixmapsink->xpixmap->height;
+               GST_DEBUG_OBJECT (evaspixmapsink, "USE ORIGIN SIZE, no geometry method" );
+       }
+#else
+       if (evaspixmapsink->keep_aspect) {
+               GstVideoRectangle src, dst;
+               /* We use the calculated geometry from _setcaps as a source to respect
+               source and screen pixel aspect ratios. */
+               src.w = GST_VIDEO_SINK_WIDTH (evaspixmapsink);
+               src.h = GST_VIDEO_SINK_HEIGHT (evaspixmapsink);
+               dst.w = evaspixmapsink->render_rect.w;
+               dst.h = evaspixmapsink->render_rect.h;
+
+               gst_video_sink_center_rect (src, dst, &result, TRUE);
+               result.x += evaspixmapsink->render_rect.x;
+               result.y += evaspixmapsink->render_rect.y;
+       } else {
+               memcpy (&result, &evaspixmapsink->render_rect, sizeof (GstVideoRectangle));
+       }
+#endif
+
+       g_mutex_lock (evaspixmapsink->x_lock);
+
+  /* We scale to the pixmap's geometry */
+#ifdef HAVE_XSHM
+       if (evaspixmapsink->xcontext->use_xshm) {
+               GST_LOG_OBJECT (evaspixmapsink,"XvShmPutImage with image %dx%d and pixmap %dx%d, from xvimage %"
+                               GST_PTR_FORMAT,
+                               evaspixmapbuf->width, evaspixmapbuf->height,
+                               evaspixmapsink->render_rect.w, evaspixmapsink->render_rect.h, evaspixmapbuf);
+
+#ifdef GST_EXT_XV_ENHANCEMENT
+       /* Trim as proper size */
+       if (src_input.w % 2 == 1) {
+               src_input.w += 1;
+       }
+       if (src_input.h % 2 == 1) {
+               src_input.h += 1;
+       }
+
+       GST_LOG_OBJECT (evaspixmapsink, "screen[%dx%d],pixmap[%d,%d,%dx%d],method[%d],rotate[%d],src[%dx%d],dst[%d,%d,%dx%d],input[%d,%d,%dx%d],result[%d,%d,%dx%d]",
+               evaspixmapsink->scr_w, evaspixmapsink->scr_h,
+               evaspixmapsink->xpixmap->x, evaspixmapsink->xpixmap->y, evaspixmapsink->xpixmap->width, evaspixmapsink->xpixmap->height,
+               evaspixmapsink->display_geometry_method, rotate,
+               src_origin.w, src_origin.h,
+               dst.x, dst.y, dst.w, dst.h,
+               src_input.x, src_input.y, src_input.w, src_input.h,
+               result.x, result.y, result.w, result.h );
+
+       if (evaspixmapsink->visible) {
+               ret = XvShmPutImage (evaspixmapsink->xcontext->disp,
+                       evaspixmapsink->xcontext->xv_port_id,
+                       evaspixmapsink->xpixmap->pixmap,
+                       evaspixmapsink->xpixmap->gc, evaspixmapbuf->xvimage,
+                       src_input.x, src_input.y, src_input.w, src_input.h,
+                       result.x, result.y, result.w, result.h, FALSE);
+               GST_LOG_OBJECT (evaspixmapsink, "XvShmPutImage return value [%d]", ret );
+
+       } else {
+               GST_WARNING_OBJECT (evaspixmapsink, "visible is FALSE. skip this image..." );
+       }
+#else /* GST_EXT_XV_ENHANCEMENT */
+       if (evaspixmapsink->visible) {
+       XvShmPutImage (evaspixmapsink->xcontext->disp,
+               evaspixmapsink->xcontext->xv_port_id,
+               evaspixmapsink->xpixmap->pixmap,
+               evaspixmapsink->xpixmap->gc, evaspixmapbuf->xvimage,
+               evaspixmapsink->disp_x, evaspixmapsink->disp_y,
+               evaspixmapsink->disp_width, evaspixmapsink->disp_height,
+               result.x, result.y, result.w, result.h, FALSE);
+       } else {
+               GST_WARNING_OBJECT (evaspixmapsink, "visible is FALSE. skip this image..." );
+       }
+#endif /* GST_EXT_XV_ENHANCEMENT */
+  } else
+#endif /* HAVE_XSHM */
+       {
+               if (evaspixmapsink->visible) {
+               XvPutImage (evaspixmapsink->xcontext->disp,
+                       evaspixmapsink->xcontext->xv_port_id,
+                       evaspixmapsink->xpixmap->pixmap,
+                       evaspixmapsink->xpixmap->gc, evaspixmapbuf->xvimage,
+                       evaspixmapsink->disp_x, evaspixmapsink->disp_y,
+                       evaspixmapsink->disp_width, evaspixmapsink->disp_height,
+                       result.x, result.y, result.w, result.h);
+               } else {
+                       GST_WARNING_OBJECT (evaspixmapsink, "visible is FALSE. skip this image..." );
+               }
+       }
+       XSync (evaspixmapsink->xcontext->disp, FALSE);
+
+       g_mutex_unlock (evaspixmapsink->x_lock);
+       g_mutex_unlock (evaspixmapsink->flow_lock);
+
+       MMTA_ACUM_ITEM_END("evaspixmapsink evaspixmap_buffer_put", FALSE);
+
+       return TRUE;
+}
+
+static int
+drm_init(GstEvasPixmapSink *evaspixmapsink)
+{
+       Display *dpy;
+       int i = 0;
+       int eventBase = 0;
+       int errorBase = 0;
+       int dri2Major = 0;
+       int dri2Minor = 0;
+       char *driverName = NULL;
+       char *deviceName = NULL;
+       struct drm_auth auth_arg = {0};
+
+       evaspixmapsink->drm_fd = -1;
+
+       dpy = XOpenDisplay(0);
+
+       /* DRI2 */
+       if (!DRI2QueryExtension(dpy, &eventBase, &errorBase)) {
+               GST_ERROR_OBJECT (evaspixmapsink,"failed to DRI2QueryExtension()");
+               goto ERROR_CASE;
+       }
+
+       if (!DRI2QueryVersion(dpy, &dri2Major, &dri2Minor)) {
+               GST_ERROR_OBJECT (evaspixmapsink,"failed to DRI2QueryVersion");
+               goto ERROR_CASE;
+       }
+
+       if (!DRI2Connect(dpy, RootWindow(dpy, DefaultScreen(dpy)), &driverName, &deviceName)) {
+               GST_ERROR_OBJECT (evaspixmapsink,"failed to DRI2Connect");
+               goto ERROR_CASE;
+       }
+
+       if (!driverName || !deviceName) {
+               GST_ERROR_OBJECT (evaspixmapsink,"driverName or deviceName is not valid");
+               goto ERROR_CASE;
+       }
+
+       GST_INFO_OBJECT (evaspixmapsink,"Open drm device : %s", deviceName);
+
+       /* get the drm_fd though opening the deviceName */
+       evaspixmapsink->drm_fd = open(deviceName, O_RDWR);
+       if (evaspixmapsink->drm_fd < 0) {
+               GST_ERROR_OBJECT (evaspixmapsink,"cannot open drm device (%s)", deviceName);
+               goto ERROR_CASE;
+       }
+
+       /* get magic from drm to authentication */
+       if (ioctl(evaspixmapsink->drm_fd, DRM_IOCTL_GET_MAGIC, &auth_arg)) {
+               GST_ERROR_OBJECT (evaspixmapsink,"cannot get drm auth magic");
+               close(evaspixmapsink->drm_fd);
+               evaspixmapsink->drm_fd = -1;
+               goto ERROR_CASE;
+       }
+
+       if (!DRI2Authenticate(dpy, RootWindow(dpy, DefaultScreen(dpy)), auth_arg.magic)) {
+               GST_ERROR_OBJECT (evaspixmapsink,"cannot get drm authentication from X");
+               close(evaspixmapsink->drm_fd);
+               evaspixmapsink->drm_fd = -1;
+               goto ERROR_CASE;
+       }
+
+       /* init gem handle */
+       for (i = 0; i < MAX_GEM_BUFFER_NUM; i++) {
+               evaspixmapsink->gem_info[i].dmabuf_fd = 0;
+               evaspixmapsink->gem_info[i].gem_handle = 0;
+               evaspixmapsink->gem_info[i].gem_name = 0;
+       }
+
+       XCloseDisplay(dpy);
+       free(driverName);
+       free(deviceName);
+
+       return 0;
+
+ERROR_CASE:
+       XCloseDisplay(dpy);
+       if (driverName) {
+               free(driverName);
+       }
+       if (deviceName) {
+               free(deviceName);
+       }
+
+       return -1;
+}
+
+static void
+drm_fini(GstEvasPixmapSink *evaspixmapsink)
+{
+       if (evaspixmapsink->drm_fd >= 0) {
+               int i = 0;
+               for (i = 0; i < MAX_GEM_BUFFER_NUM; i++) {
+                       if (evaspixmapsink->gem_info[i].dmabuf_fd > 0) {
+                               GST_INFO_OBJECT (evaspixmapsink,"close gem_handle(%u)", evaspixmapsink->gem_info[i].gem_handle);
+                               drm_close_gem(evaspixmapsink, evaspixmapsink->gem_info[i].gem_handle);
+
+                               evaspixmapsink->gem_info[i].dmabuf_fd = 0;
+                               evaspixmapsink->gem_info[i].gem_handle = 0;
+                               evaspixmapsink->gem_info[i].gem_name = 0;
+                       } else {
+                               break;
+                       }
+               }
+               GST_INFO_OBJECT (evaspixmapsink,"close drm_fd(%d)", evaspixmapsink->drm_fd);
+               close(evaspixmapsink->drm_fd);
+               evaspixmapsink->drm_fd = -1;
+       }
+}
+
+static unsigned int
+drm_convert_dmabuf_gemname(GstEvasPixmapSink *evaspixmapsink, int dmabuf_fd)
+{
+       struct drm_prime_handle prime_arg = {0,};
+       struct drm_gem_flink flink_arg = {0,};
+       int i = 0;
+
+       if (evaspixmapsink->drm_fd < 0) {
+               GST_ERROR_OBJECT (evaspixmapsink,"DRM is not opened");
+               return 0;
+       }
+
+       if (dmabuf_fd <= 0) {
+               GST_DEBUG_OBJECT (evaspixmapsink,"Ignore wrong dmabuf fd(%d)", dmabuf_fd);              /* temporarily change log level to DEBUG for reducing WARNING level log */
+               return 0;
+       }
+
+       /* check duplicated dmabuf fd */
+       for (i = 0 ; i < MAX_GEM_BUFFER_NUM ; i++) {
+               if (evaspixmapsink->gem_info[i].dmabuf_fd == dmabuf_fd) {
+                       GST_LOG_OBJECT (evaspixmapsink,"already got fd(%u) with name(%u)", dmabuf_fd, evaspixmapsink->gem_info[i].gem_name);
+                       return evaspixmapsink->gem_info[i].gem_name;
+               }
+
+               if (evaspixmapsink->gem_info[i].dmabuf_fd == 0) {
+                       GST_LOG_OBJECT (evaspixmapsink,"empty gem_info[%d] found", i);
+                       break;
+               }
+       }
+
+       if (i == MAX_GEM_BUFFER_NUM) {
+               GST_WARNING_OBJECT (evaspixmapsink,"too many buffers[dmabuf_fd(%d). skip it]", dmabuf_fd);
+               return 0;
+       }
+
+       evaspixmapsink->gem_info[i].dmabuf_fd = dmabuf_fd;
+       prime_arg.fd = dmabuf_fd;
+       if (ioctl(evaspixmapsink->drm_fd, DRM_IOCTL_PRIME_FD_TO_HANDLE, &prime_arg)) {
+               GST_ERROR_OBJECT (evaspixmapsink,"non dmabuf fd(%d)", dmabuf_fd);
+               return 0;
+       }
+
+       evaspixmapsink->gem_info[i].gem_handle = prime_arg.handle;
+       GST_LOG_OBJECT (evaspixmapsink,"gem_info[%d].gem_handle = %u", i, prime_arg.handle);
+
+       flink_arg.handle = prime_arg.handle;
+       if (ioctl(evaspixmapsink->drm_fd, DRM_IOCTL_GEM_FLINK, &flink_arg)) {
+               GST_ERROR_OBJECT (evaspixmapsink,"cannot convert drm handle to name");
+               return 0;
+       }
+
+       evaspixmapsink->gem_info[i].gem_name = flink_arg.name;
+       GST_LOG_OBJECT (evaspixmapsink,"gem_info[%d].gem_name = %u", i, flink_arg.name);
+
+       return flink_arg.name;
+}
+
+static void
+drm_close_gem(GstEvasPixmapSink *evaspixmapsink, unsigned int gem_handle)
+{
+       struct drm_gem_close close_arg = {0,};
+
+       if (evaspixmapsink->drm_fd < 0) {
+               GST_ERROR_OBJECT (evaspixmapsink,"DRM is not opened");
+               return;
+       }
+
+       if (gem_handle == 0) {
+               GST_ERROR_OBJECT (evaspixmapsink,"invalid gem_handle(%d)",gem_handle);
+               return;
+       }
+
+       close_arg.handle = gem_handle;
+       if (gem_handle > 0 && ioctl(evaspixmapsink->drm_fd, DRM_IOCTL_GEM_CLOSE, &close_arg)) {
+               GST_ERROR_OBJECT (evaspixmapsink,"cannot close drm gem handle(%d)", gem_handle);
+               return;
+       }
+
+       return;
+}
+
+/* This function destroys a GstXPixmap */
+static void
+gst_evaspixmapsink_xpixmap_destroy (GstEvasPixmapSink *evaspixmapsink, GstXPixmap *xpixmap)
+{
+       g_return_if_fail (xpixmap != NULL);
+       g_return_if_fail (GST_IS_EVASPIXMAPSINK (evaspixmapsink));
+
+       g_mutex_lock (evaspixmapsink->x_lock);
+
+       if(evaspixmapsink->xpixmap->pixmap) {
+               XFreePixmap(evaspixmapsink->xcontext->disp, evaspixmapsink->xpixmap->pixmap);
+               evaspixmapsink->xpixmap->pixmap = NULL;
+               GST_DEBUG_OBJECT (evaspixmapsink,"Free pixmap");
+       }
+
+       if (xpixmap->gc) {
+               XFreeGC (evaspixmapsink->xcontext->disp, xpixmap->gc);
+       }
+
+       XSync (evaspixmapsink->xcontext->disp, FALSE);
+
+       g_mutex_unlock (evaspixmapsink->x_lock);
+
+       g_free (xpixmap);
+}
+
+static void
+gst_evaspixmapsink_xpixmap_update_geometry (GstEvasPixmapSink *evaspixmapsink)
+{
+#ifdef GST_EXT_XV_ENHANCEMENT
+       Window root_window;
+       XWindowAttributes root_attr;
+
+       int cur_pixmap_x = 0;
+       int cur_pixmap_y = 0;
+       unsigned int cur_pixmap_width = 0;
+       unsigned int cur_pixmap_height = 0;
+       unsigned int cur_pixmap_border_width = 0;
+       unsigned int cur_pixmap_depth = 0;
+#else
+       XWindowAttributes attr;
+#endif
+       g_return_if_fail (GST_IS_EVASPIXMAPSINK (evaspixmapsink));
+
+       /* Update the window geometry */
+       g_mutex_lock (evaspixmapsink->x_lock);
+       if (G_UNLIKELY (evaspixmapsink->xpixmap == NULL)) {
+               g_mutex_unlock (evaspixmapsink->x_lock);
+               return;
+       }
+
+#ifdef GST_EXT_XV_ENHANCEMENT
+       /* Get root window and size of current pixmap */
+       XGetGeometry( evaspixmapsink->xcontext->disp, evaspixmapsink->xpixmap->pixmap, &root_window,
+                       &cur_pixmap_x, &cur_pixmap_y, /* relative x, y, for pixmap these are alway 0 */
+                       &cur_pixmap_width, &cur_pixmap_height,
+                       &cur_pixmap_border_width, &cur_pixmap_depth ); /* cur_pixmap_border_width, cur_pixmap_depth are not used */
+
+       evaspixmapsink->xpixmap->width = cur_pixmap_width;
+       evaspixmapsink->xpixmap->height = cur_pixmap_height;
+
+       evaspixmapsink->xpixmap->x = cur_pixmap_x;
+       evaspixmapsink->xpixmap->y = cur_pixmap_y;
+
+       /* Get size of root window == size of screen */
+       XGetWindowAttributes(evaspixmapsink->xcontext->disp, root_window, &root_attr);
+
+       evaspixmapsink->scr_w = root_attr.width;
+       evaspixmapsink->scr_h = root_attr.height;
+
+       if (!evaspixmapsink->have_render_rect) {
+               evaspixmapsink->render_rect.x = evaspixmapsink->render_rect.y = 0;
+               evaspixmapsink->render_rect.w = cur_pixmap_width;
+               evaspixmapsink->render_rect.h = cur_pixmap_height;
+       }
+
+       GST_LOG_OBJECT (evaspixmapsink,"screen size %dx%d, current pixmap geometry %d,%d,%dx%d, render_rect %d,%d,%dx%d",
+                       evaspixmapsink->scr_w, evaspixmapsink->scr_h,
+                       evaspixmapsink->xpixmap->x, evaspixmapsink->xpixmap->y,
+                       evaspixmapsink->xpixmap->width, evaspixmapsink->xpixmap->height,
+                       evaspixmapsink->render_rect.x, evaspixmapsink->render_rect.y,
+                       evaspixmapsink->render_rect.w, evaspixmapsink->render_rect.h);
+#else
+       XGetWindowAttributes (evaspixmapsink->xcontext->disp, evaspixmapsink->xpixmap->pixmap, &attr);
+
+       evaspixmapsink->xpixmap->width = attr.width;
+       evaspixmapsink->xpixmap->height = attr.height;
+
+       if (!evaspixmapsink->have_render_rect) {
+               evaspixmapsink->render_rect.x = evaspixmapsink->render_rect.y = 0;
+               evaspixmapsink->render_rect.w = attr.width;
+               evaspixmapsink->render_rect.h = attr.height;
+       }
+#endif
+       g_mutex_unlock (evaspixmapsink->x_lock);
+}
+
+static void
+gst_evaspixmapsink_xpixmap_clear (GstEvasPixmapSink *evaspixmapsink, GstXPixmap *xpixmap)
+{
+       g_return_if_fail (xpixmap != NULL);
+       g_return_if_fail (GST_IS_EVASPIXMAPSINK (evaspixmapsink));
+
+       if (!xpixmap->pixmap) {
+               GST_WARNING_OBJECT (evaspixmapsink,"pixmap was not created..");
+               return;
+       }
+
+       g_mutex_lock (evaspixmapsink->x_lock);
+
+       if( evaspixmapsink->stop_video ) {
+               XvStopVideo (evaspixmapsink->xcontext->disp, evaspixmapsink->xcontext->xv_port_id, xpixmap->pixmap);
+       }
+       /* Preview area is not updated before other UI is updated in the screen. */
+       XSetForeground (evaspixmapsink->xcontext->disp, xpixmap->gc, evaspixmapsink->xcontext->black);
+       XFillRectangle (evaspixmapsink->xcontext->disp, xpixmap->pixmap, xpixmap->gc,
+               evaspixmapsink->render_rect.x, evaspixmapsink->render_rect.y, evaspixmapsink->render_rect.w, evaspixmapsink->render_rect.h);
+
+       XSync (evaspixmapsink->xcontext->disp, FALSE);
+
+       g_mutex_unlock (evaspixmapsink->x_lock);
+}
+
+/* This function commits our internal colorbalance settings to our grabbed Xv
+   port. If the xcontext is not initialized yet it simply returns */
+static void
+gst_evaspixmapsink_update_colorbalance (GstEvasPixmapSink *evaspixmapsink)
+{
+  GList *channels = NULL;
+
+  g_return_if_fail (GST_IS_EVASPIXMAPSINK (evaspixmapsink));
+
+  /* If we haven't initialized the X context we can't update anything */
+  if (evaspixmapsink->xcontext == NULL)
+    return;
+
+  /* Don't set the attributes if they haven't been changed, to avoid
+   * rounding errors changing the values */
+  if (!evaspixmapsink->cb_changed)
+    return;
+
+  /* For each channel of the colorbalance we calculate the correct value
+     doing range conversion and then set the Xv port attribute to match our
+     values. */
+  channels = evaspixmapsink->xcontext->channels_list;
+
+  while (channels) {
+    if (channels->data && GST_IS_COLOR_BALANCE_CHANNEL (channels->data)) {
+      GstColorBalanceChannel *channel = NULL;
+      Atom prop_atom;
+      gint value = 0;
+      gdouble convert_coef;
+
+      channel = GST_COLOR_BALANCE_CHANNEL (channels->data);
+      g_object_ref (channel);
+
+      /* Our range conversion coef */
+      convert_coef = (channel->max_value - channel->min_value) / 2000.0;
+
+      if (g_ascii_strcasecmp (channel->label, "XV_HUE") == 0) {
+        value = evaspixmapsink->hue;
+      } else if (g_ascii_strcasecmp (channel->label, "XV_SATURATION") == 0) {
+        value = evaspixmapsink->saturation;
+      } else if (g_ascii_strcasecmp (channel->label, "XV_CONTRAST") == 0) {
+        value = evaspixmapsink->contrast;
+      } else if (g_ascii_strcasecmp (channel->label, "XV_BRIGHTNESS") == 0) {
+        value = evaspixmapsink->brightness;
+      } else {
+        g_warning ("got an unknown channel %s", channel->label);
+        g_object_unref (channel);
+        return;
+      }
+
+      /* Committing to Xv port */
+      g_mutex_lock (evaspixmapsink->x_lock);
+      prop_atom =
+          XInternAtom (evaspixmapsink->xcontext->disp, channel->label, True);
+      if (prop_atom != None) {
+        int xv_value;
+        xv_value =
+            floor (0.5 + (value + 1000) * convert_coef + channel->min_value);
+        XvSetPortAttribute (evaspixmapsink->xcontext->disp,
+            evaspixmapsink->xcontext->xv_port_id, prop_atom, xv_value);
+      }
+      g_mutex_unlock (evaspixmapsink->x_lock);
+
+      g_object_unref (channel);
+    }
+    channels = g_list_next (channels);
+  }
+}
+
+static void
+gst_lookup_xv_port_from_adaptor (GstXContext *xcontext, XvAdaptorInfo *adaptors, int adaptor_no)
+{
+  gint j;
+  gint res;
+
+  /* Do we support XvImageMask ? */
+  if (!(adaptors[adaptor_no].type & XvImageMask)) {
+    GST_DEBUG ("XV Adaptor %s has no support for XvImageMask", adaptors[adaptor_no].name);
+    return;
+  }
+
+  /* We found such an adaptor, looking for an available port */
+  for (j = 0; j < adaptors[adaptor_no].num_ports && !xcontext->xv_port_id; j++) {
+    /* We try to grab the port */
+    res = XvGrabPort (xcontext->disp, adaptors[adaptor_no].base_id + j, 0);
+    if (Success == res) {
+      xcontext->xv_port_id = adaptors[adaptor_no].base_id + j;
+      GST_DEBUG ("XV Adaptor %s with %ld ports", adaptors[adaptor_no].name, adaptors[adaptor_no].num_ports);
+    } else {
+      GST_DEBUG ("GrabPort %d for XV Adaptor %s failed: %d", j, adaptors[adaptor_no].name, res);
+    }
+  }
+}
+
+/* This function generates a caps with all supported format by the first
+   Xv grabable port we find. We store each one of the supported formats in a
+   format list and append the format to a newly created caps that we return
+   If this function does not return NULL because of an error, it also grabs
+   the port via XvGrabPort */
+static GstCaps*
+gst_evaspixmapsink_get_xv_support (GstEvasPixmapSink *evaspixmapsink, GstXContext *xcontext)
+{
+  gint i;
+  XvAdaptorInfo *adaptors;
+  gint nb_formats;
+  XvImageFormatValues *formats = NULL;
+  guint nb_encodings;
+  XvEncodingInfo *encodings = NULL;
+  gulong max_w = G_MAXINT, max_h = G_MAXINT;
+  GstCaps *caps = NULL;
+  GstCaps *rgb_caps = NULL;
+
+  g_return_val_if_fail (xcontext != NULL, NULL);
+
+  /* First let's check that XVideo extension is available */
+  if (!XQueryExtension (xcontext->disp, "XVideo", &i, &i, &i)) {
+    GST_ELEMENT_ERROR (evaspixmapsink, RESOURCE, SETTINGS,
+        ("Could not initialise Xv output"),
+        ("XVideo extension is not available"));
+    return NULL;
+  }
+
+  /* Then we get adaptors list */
+  if (Success != XvQueryAdaptors (xcontext->disp, xcontext->root,
+          &xcontext->nb_adaptors, &adaptors)) {
+    GST_ELEMENT_ERROR (evaspixmapsink, RESOURCE, SETTINGS,
+        ("Could not initialise Xv output"),
+        ("Failed getting XV adaptors list"));
+    return NULL;
+  }
+
+  xcontext->xv_port_id = 0;
+
+  GST_DEBUG_OBJECT (evaspixmapsink,"Found %u XV adaptor(s)", xcontext->nb_adaptors);
+
+  xcontext->adaptors =
+      (gchar **) g_malloc0 (xcontext->nb_adaptors * sizeof (gchar *));
+
+  /* Now fill up our adaptor name array */
+  for (i = 0; i < xcontext->nb_adaptors; i++) {
+    xcontext->adaptors[i] = g_strdup (adaptors[i].name);
+  }
+
+  if (evaspixmapsink->adaptor_no < xcontext->nb_adaptors) {
+    /* Find xv port from user defined adaptor */
+    gst_lookup_xv_port_from_adaptor (xcontext, adaptors, evaspixmapsink->adaptor_no);
+  }
+
+  if (!xcontext->xv_port_id) {
+    /* Now search for an adaptor that supports XvImageMask */
+    for (i = 0; i < xcontext->nb_adaptors && !xcontext->xv_port_id; i++) {
+      gst_lookup_xv_port_from_adaptor (xcontext, adaptors, i);
+      evaspixmapsink->adaptor_no = i;
+    }
+  }
+
+  XvFreeAdaptorInfo (adaptors);
+
+  if (!xcontext->xv_port_id) {
+    evaspixmapsink->adaptor_no = -1;
+    GST_ELEMENT_ERROR (evaspixmapsink, RESOURCE, BUSY,
+        ("Could not initialise Xv output"), ("No port available"));
+    return NULL;
+  }
+
+  /* Set XV_AUTOPAINT_COLORKEY and XV_DOUBLE_BUFFER and XV_COLORKEY */
+  {
+    int count, todo = 3;
+    XvAttribute *const attr = XvQueryPortAttributes (xcontext->disp,
+        xcontext->xv_port_id, &count);
+    static const char autopaint[] = "XV_AUTOPAINT_COLORKEY";
+    static const char dbl_buffer[] = "XV_DOUBLE_BUFFER";
+    static const char colorkey[] = "XV_COLORKEY";
+
+    GST_DEBUG_OBJECT (evaspixmapsink,"Checking %d Xv port attributes", count);
+
+    evaspixmapsink->have_autopaint_colorkey = FALSE;
+    evaspixmapsink->have_double_buffer = FALSE;
+    evaspixmapsink->have_colorkey = FALSE;
+
+    for (i = 0; ((i < count) && todo); i++)
+      if (!strcmp (attr[i].name, autopaint)) {
+        const Atom atom = XInternAtom (xcontext->disp, autopaint, False);
+
+        /* turn on autopaint colorkey */
+        XvSetPortAttribute (xcontext->disp, xcontext->xv_port_id, atom,
+            (evaspixmapsink->autopaint_colorkey ? 1 : 0));
+        todo--;
+        evaspixmapsink->have_autopaint_colorkey = TRUE;
+      } else if (!strcmp (attr[i].name, dbl_buffer)) {
+        const Atom atom = XInternAtom (xcontext->disp, dbl_buffer, False);
+
+        XvSetPortAttribute (xcontext->disp, xcontext->xv_port_id, atom,
+            (evaspixmapsink->double_buffer ? 1 : 0));
+        todo--;
+        evaspixmapsink->have_double_buffer = TRUE;
+      } else if (!strcmp (attr[i].name, colorkey)) {
+        /* Set the colorkey, default is something that is dark but hopefully
+         * won't randomly appear on the screen elsewhere (ie not black or greys)
+         * can be overridden by setting "colorkey" property
+         */
+        const Atom atom = XInternAtom (xcontext->disp, colorkey, False);
+        guint32 ckey = 0;
+        gboolean set_attr = TRUE;
+        guint cr, cg, cb;
+
+        /* set a colorkey in the right format RGB565/RGB888
+         * We only handle these 2 cases, because they're the only types of
+         * devices we've encountered. If we don't recognise it, leave it alone
+         */
+        cr = (evaspixmapsink->colorkey >> 16);
+        cg = (evaspixmapsink->colorkey >> 8) & 0xFF;
+        cb = (evaspixmapsink->colorkey) & 0xFF;
+        switch (xcontext->depth) {
+          case 16:             /* RGB 565 */
+            cr >>= 3;
+            cg >>= 2;
+            cb >>= 3;
+            ckey = (cr << 11) | (cg << 5) | cb;
+            break;
+          case 24:
+          case 32:             /* RGB 888 / ARGB 8888 */
+            ckey = (cr << 16) | (cg << 8) | cb;
+            break;
+          default:
+            GST_DEBUG_OBJECT (evaspixmapsink,"Unknown bit depth %d for Xv Colorkey - not adjusting", xcontext->depth);
+            set_attr = FALSE;
+            break;
+        }
+
+        if (set_attr) {
+          ckey = CLAMP (ckey, (guint32) attr[i].min_value,
+              (guint32) attr[i].max_value);
+          GST_LOG_OBJECT (evaspixmapsink,"Setting color key for display depth %d to 0x%x", xcontext->depth, ckey);
+
+          XvSetPortAttribute (xcontext->disp, xcontext->xv_port_id, atom,
+              (gint) ckey);
+        }
+        todo--;
+        evaspixmapsink->have_colorkey = TRUE;
+      }
+
+    XFree (attr);
+  }
+
+  /* Get the list of encodings supported by the adapter and look for the
+   * XV_IMAGE encoding so we can determine the maximum width and height
+   * supported */
+  XvQueryEncodings (xcontext->disp, xcontext->xv_port_id, &nb_encodings,
+      &encodings);
+
+  for (i = 0; i < nb_encodings; i++) {
+    GST_LOG_OBJECT (evaspixmapsink,
+        "Encoding %d, name %s, max wxh %lux%lu rate %d/%d",
+        i, encodings[i].name, encodings[i].width, encodings[i].height,
+        encodings[i].rate.numerator, encodings[i].rate.denominator);
+    if (strcmp (encodings[i].name, "XV_IMAGE") == 0) {
+      max_w = encodings[i].width;
+      max_h = encodings[i].height;
+#ifdef GST_EXT_XV_ENHANCEMENT
+      evaspixmapsink->scr_w = max_w;
+      evaspixmapsink->scr_h = max_h;
+#endif
+    }
+  }
+
+  XvFreeEncodingInfo (encodings);
+
+  /* We get all image formats supported by our port */
+  formats = XvListImageFormats (xcontext->disp,
+      xcontext->xv_port_id, &nb_formats);
+  caps = gst_caps_new_empty ();
+  for (i = 0; i < nb_formats; i++) {
+    GstCaps *format_caps = NULL;
+    gboolean is_rgb_format = FALSE;
+
+    /* We set the image format of the xcontext to an existing one. This
+       is just some valid image format for making our xshm calls check before
+       caps negotiation really happens. */
+    xcontext->im_format = formats[i].id;
+
+    switch (formats[i].type) {
+      case XvRGB:
+      {
+        XvImageFormatValues *fmt = &(formats[i]);
+        gint endianness = G_BIG_ENDIAN;
+
+        if (fmt->byte_order == LSBFirst) {
+          /* our caps system handles 24/32bpp RGB as big-endian. */
+          if (fmt->bits_per_pixel == 24 || fmt->bits_per_pixel == 32) {
+            fmt->red_mask = GUINT32_TO_BE (fmt->red_mask);
+            fmt->green_mask = GUINT32_TO_BE (fmt->green_mask);
+            fmt->blue_mask = GUINT32_TO_BE (fmt->blue_mask);
+
+            if (fmt->bits_per_pixel == 24) {
+              fmt->red_mask >>= 8;
+              fmt->green_mask >>= 8;
+              fmt->blue_mask >>= 8;
+            }
+          } else
+            endianness = G_LITTLE_ENDIAN;
+        }
+
+        format_caps = gst_caps_new_simple ("video/x-raw-rgb",
+            "endianness", G_TYPE_INT, endianness,
+            "depth", G_TYPE_INT, fmt->depth,
+            "bpp", G_TYPE_INT, fmt->bits_per_pixel,
+            "red_mask", G_TYPE_INT, fmt->red_mask,
+            "green_mask", G_TYPE_INT, fmt->green_mask,
+            "blue_mask", G_TYPE_INT, fmt->blue_mask,
+            "width", GST_TYPE_INT_RANGE, 1, max_w,
+            "height", GST_TYPE_INT_RANGE, 1, max_h,
+            "framerate", GST_TYPE_FRACTION_RANGE, 0, 1, G_MAXINT, 1, NULL);
+
+        is_rgb_format = TRUE;
+        break;
+      }
+      case XvYUV:
+        format_caps = gst_caps_new_simple ("video/x-raw-yuv",
+            "format", GST_TYPE_FOURCC, formats[i].id,
+            "width", GST_TYPE_INT_RANGE, 1, max_w,
+            "height", GST_TYPE_INT_RANGE, 1, max_h,
+            "framerate", GST_TYPE_FRACTION_RANGE, 0, 1, G_MAXINT, 1, NULL);
+        break;
+      default:
+        g_assert_not_reached ();
+        break;
+    }
+
+    if (format_caps) {
+      GstEvasPixmapFormat *format = NULL;
+
+      format = g_new0 (GstEvasPixmapFormat, 1);
+      if (format) {
+        format->format = formats[i].id;
+        format->caps = gst_caps_copy (format_caps);
+        xcontext->formats_list = g_list_append (xcontext->formats_list, format);
+      }
+
+      if (is_rgb_format) {
+        if (rgb_caps == NULL)
+          rgb_caps = format_caps;
+        else
+          gst_caps_append (rgb_caps, format_caps);
+      } else
+        gst_caps_append (caps, format_caps);
+    }
+  }
+
+  /* Collected all caps into either the caps or rgb_caps structures.
+   * Append rgb_caps on the end of YUV, so that YUV is always preferred */
+  if (rgb_caps)
+    gst_caps_append (caps, rgb_caps);
+
+  if (formats)
+    XFree (formats);
+
+  GST_DEBUG_OBJECT (evaspixmapsink,"Generated the following caps: %" GST_PTR_FORMAT, caps);
+
+  if (gst_caps_is_empty (caps)) {
+    gst_caps_unref (caps);
+    XvUngrabPort (xcontext->disp, xcontext->xv_port_id, 0);
+    GST_ELEMENT_ERROR (evaspixmapsink, STREAM, WRONG_TYPE, (NULL),
+        ("No supported format found"));
+    return NULL;
+  }
+
+  return caps;
+}
+
+static gpointer
+gst_evaspixmapsink_event_thread (GstEvasPixmapSink * evaspixmapsink)
+{
+       g_return_val_if_fail (GST_IS_EVASPIXMAPSINK (evaspixmapsink), NULL);
+       int damage_base = 0;
+       int damage_err_base = 0;
+       int damage_case = 0;
+       XEvent e;
+
+       GST_OBJECT_LOCK (evaspixmapsink);
+
+       if (!XDamageQueryExtension(evaspixmapsink->xcontext->disp, &damage_base, &damage_err_base)) {
+               GST_ERROR_OBJECT (evaspixmapsink,"XDamageQueryExtension() failed");
+               return NULL;
+       }
+       damage_case = (int)damage_base + XDamageNotify;
+
+       while (evaspixmapsink->running) {
+               GST_OBJECT_UNLOCK (evaspixmapsink);
+               if (evaspixmapsink->xpixmap) {
+                       g_mutex_lock (evaspixmapsink->x_lock);
+                       while (XPending (evaspixmapsink->xcontext->disp)) {
+                               XNextEvent (evaspixmapsink->xcontext->disp, &e);
+                               if (e.type == damage_case ) {
+                                       XDamageNotifyEvent *damage_ev = (XDamageNotifyEvent *)&e;
+                                       if (damage_ev->drawable == evaspixmapsink->xpixmap->pixmap) {
+                                               __ta__("evaspixmapsink ecore_pipe_write", ecore_pipe_write(evaspixmapsink->epipe, evaspixmapsink, sizeof(GstEvasPixmapSink)););
+                                               GST_DEBUG_OBJECT (evaspixmapsink,"event_handler : after call ecore_pipe_write()");
+                                       }
+                                       XDamageSubtract (evaspixmapsink->xcontext->disp, evaspixmapsink->damage, None, None );
+                               }
+                       }
+                       g_mutex_unlock (evaspixmapsink->x_lock);
+               } else {
+                       GST_DEBUG_OBJECT (evaspixmapsink,"event_handler : what(%d)? skip..", e.type);
+                       break;
+               }
+               g_usleep (G_USEC_PER_SEC / 40);
+               GST_OBJECT_LOCK (evaspixmapsink);
+       }
+       GST_OBJECT_UNLOCK (evaspixmapsink);
+       return NULL;
+}
+
+static void
+gst_evaspixmapsink_manage_event_thread (GstEvasPixmapSink *evaspixmapsink)
+{
+       GThread *thread = NULL;
+
+       /* don't start the thread too early */
+       if (evaspixmapsink->xcontext == NULL) {
+               GST_ERROR_OBJECT (evaspixmapsink,"xcontext is NULL..");
+               return;
+       }
+
+       GST_OBJECT_LOCK (evaspixmapsink);
+
+       if (!evaspixmapsink->event_thread) {
+               /* Setup our event listening thread */
+               GST_DEBUG_OBJECT (evaspixmapsink,"run xevent thread");
+               evaspixmapsink->running = TRUE;
+               evaspixmapsink->event_thread = g_thread_create ( (GThreadFunc) gst_evaspixmapsink_event_thread, evaspixmapsink, TRUE, NULL);
+       } else {
+               GST_WARNING_OBJECT (evaspixmapsink,"there already existed the event_thread.. keep going");
+               /* Do not finalize the thread in here, Only finalize the thread by calling gst_evaspixmapsink_reset() */
+       }
+
+       GST_OBJECT_UNLOCK (evaspixmapsink);
+}
+
+
+/* This function calculates the pixel aspect ratio based on the properties
+ * in the xcontext structure and stores it there. */
+static void
+gst_evaspixmapsink_calculate_pixel_aspect_ratio (GstXContext *xcontext)
+{
+  static const gint par[][2] = {
+    {1, 1},                     /* regular screen */
+    {16, 15},                   /* PAL TV */
+    {11, 10},                   /* 525 line Rec.601 video */
+    {54, 59},                   /* 625 line Rec.601 video */
+    {64, 45},                   /* 1280x1024 on 16:9 display */
+    {5, 3},                     /* 1280x1024 on 4:3 display */
+    {4, 3}                      /*  800x600 on 16:9 display */
+  };
+  gint i;
+  gint index;
+  gdouble ratio;
+  gdouble delta;
+
+#define DELTA(idx) (ABS (ratio - ((gdouble) par[idx][0] / par[idx][1])))
+
+  /* first calculate the "real" ratio based on the X values;
+   * which is the "physical" w/h divided by the w/h in pixels of the display */
+  ratio = (gdouble) (xcontext->widthmm * xcontext->height)
+      / (xcontext->heightmm * xcontext->width);
+
+  /* DirectFB's X in 720x576 reports the physical dimensions wrong, so
+   * override here */
+  if (xcontext->width == 720 && xcontext->height == 576) {
+    ratio = 4.0 * 576 / (3.0 * 720);
+  }
+  GST_DEBUG ("calculated pixel aspect ratio: %f", ratio);
+  /* now find the one from par[][2] with the lowest delta to the real one */
+  delta = DELTA (0);
+  index = 0;
+
+  for (i = 1; i < sizeof (par) / (sizeof (gint) * 2); ++i) {
+    gdouble this_delta = DELTA (i);
+
+    if (this_delta < delta) {
+      index = i;
+      delta = this_delta;
+    }
+  }
+
+  GST_DEBUG ("Decided on index %d (%d/%d)", index,
+      par[index][0], par[index][1]);
+
+  g_free (xcontext->par);
+  xcontext->par = g_new0 (GValue, 1);
+  g_value_init (xcontext->par, GST_TYPE_FRACTION);
+  gst_value_set_fraction (xcontext->par, par[index][0], par[index][1]);
+  GST_DEBUG ("set xcontext PAR to %d/%d",
+      gst_value_get_fraction_numerator (xcontext->par),
+      gst_value_get_fraction_denominator (xcontext->par));
+}
+
+/* This function gets the X Display and global info about it. Everything is
+   stored in our object and will be cleaned when the object is disposed. Note
+   here that caps for supported format are generated without any window or
+   image creation */
+static GstXContext*
+gst_evaspixmapsink_xcontext_get (GstEvasPixmapSink *evaspixmapsink)
+{
+       GstXContext *xcontext = NULL;
+       XPixmapFormatValues *px_formats = NULL;
+       gint nb_formats = 0, i, j, N_attr;
+       XvAttribute *xv_attr;
+       Atom prop_atom;
+       const char *channels[4] = { "XV_HUE", "XV_SATURATION", "XV_BRIGHTNESS", "XV_CONTRAST"};
+
+       g_return_val_if_fail (GST_IS_EVASPIXMAPSINK (evaspixmapsink), NULL);
+
+       xcontext = g_new0 (GstXContext, 1);
+       xcontext->im_format = 0;
+
+       g_mutex_lock (evaspixmapsink->x_lock);
+
+       xcontext->disp = XOpenDisplay (evaspixmapsink->display_name);
+
+       if (!xcontext->disp) {
+               g_mutex_unlock (evaspixmapsink->x_lock);
+               g_free (xcontext);
+               GST_ELEMENT_ERROR (evaspixmapsink, RESOURCE, WRITE, ("Could not initialise Xv output"), ("Could not open display"));
+               return NULL;
+       }
+
+       xcontext->screen = DefaultScreenOfDisplay (xcontext->disp);
+       xcontext->screen_num = DefaultScreen (xcontext->disp);
+       xcontext->visual = DefaultVisual (xcontext->disp, xcontext->screen_num);
+       xcontext->root = DefaultRootWindow (xcontext->disp);
+       xcontext->white = XWhitePixel (xcontext->disp, xcontext->screen_num);
+       xcontext->black = XBlackPixel (xcontext->disp, xcontext->screen_num);
+       xcontext->depth = DefaultDepthOfScreen (xcontext->screen);
+
+       xcontext->width = DisplayWidth (xcontext->disp, xcontext->screen_num);
+       xcontext->height = DisplayHeight (xcontext->disp, xcontext->screen_num);
+       xcontext->widthmm = DisplayWidthMM (xcontext->disp, xcontext->screen_num);
+       xcontext->heightmm = DisplayHeightMM (xcontext->disp, xcontext->screen_num);
+
+       GST_DEBUG_OBJECT (evaspixmapsink,"X reports %dx%d pixels and %d mm x %d mm", xcontext->width, xcontext->height, xcontext->widthmm, xcontext->heightmm);
+
+       gst_evaspixmapsink_calculate_pixel_aspect_ratio (xcontext);
+       /* We get supported pixmap formats at supported depth */
+       px_formats = XListPixmapFormats (xcontext->disp, &nb_formats);
+
+       if (!px_formats) {
+               XCloseDisplay (xcontext->disp);
+               g_mutex_unlock (evaspixmapsink->x_lock);
+               g_free (xcontext->par);
+               g_free (xcontext);
+               GST_ELEMENT_ERROR (evaspixmapsink, RESOURCE, SETTINGS,
+               ("Could not initialise Xv output"), ("Could not get pixel formats"));
+               return NULL;
+       }
+
+       /* We get bpp value corresponding to our running depth */
+       for (i = 0; i < nb_formats; i++) {
+               if (px_formats[i].depth == xcontext->depth)
+               xcontext->bpp = px_formats[i].bits_per_pixel;
+       }
+
+       XFree (px_formats);
+
+       xcontext->endianness = (ImageByteOrder (xcontext->disp) == LSBFirst) ? G_LITTLE_ENDIAN : G_BIG_ENDIAN;
+
+       /* our caps system handles 24/32bpp RGB as big-endian. */
+       if ((xcontext->bpp == 24 || xcontext->bpp == 32) && xcontext->endianness == G_LITTLE_ENDIAN) {
+               xcontext->endianness = G_BIG_ENDIAN;
+               xcontext->visual->red_mask = GUINT32_TO_BE (xcontext->visual->red_mask);
+               xcontext->visual->green_mask = GUINT32_TO_BE (xcontext->visual->green_mask);
+               xcontext->visual->blue_mask = GUINT32_TO_BE (xcontext->visual->blue_mask);
+               if (xcontext->bpp == 24) {
+                       xcontext->visual->red_mask >>= 8;
+                       xcontext->visual->green_mask >>= 8;
+                       xcontext->visual->blue_mask >>= 8;
+               }
+       }
+
+       xcontext->caps = gst_evaspixmapsink_get_xv_support (evaspixmapsink, xcontext);
+
+       if (!xcontext->caps) {
+               XCloseDisplay (xcontext->disp);
+               g_mutex_unlock (evaspixmapsink->x_lock);
+               g_free (xcontext->par);
+               g_free (xcontext);
+               /* GST_ELEMENT_ERROR is thrown by gst_evaspixmapsink_get_xv_support */
+               return NULL;
+       }
+       #ifdef HAVE_XSHM
+       /* Search for XShm extension support */
+       if (XShmQueryExtension (xcontext->disp) && gst_evaspixmapsink_check_xshm_calls (xcontext)) {
+               xcontext->use_xshm = TRUE;
+               GST_DEBUG_OBJECT (evaspixmapsink,"evaspixmapsink is using XShm extension");
+       } else
+       #endif /* HAVE_XSHM */
+       {
+               xcontext->use_xshm = FALSE;
+               GST_DEBUG_OBJECT (evaspixmapsink,"evaspixmapsink is not using XShm extension");
+       }
+
+       xv_attr = XvQueryPortAttributes (xcontext->disp, xcontext->xv_port_id, &N_attr);
+
+       /* Generate the channels list */
+       for (i = 0; i < (sizeof (channels) / sizeof (char *)); i++) {
+               XvAttribute *matching_attr = NULL;
+
+               /* Retrieve the property atom if it exists. If it doesn't exist,
+               * the attribute itself must not either, so we can skip */
+               prop_atom = XInternAtom (xcontext->disp, channels[i], True);
+               if (prop_atom == None) {
+                       continue;
+               }
+
+               if (xv_attr != NULL) {
+                       for (j = 0; j < N_attr && matching_attr == NULL; ++j) {
+                               if (!g_ascii_strcasecmp (channels[i], xv_attr[j].name)) {
+                                       matching_attr = xv_attr + j;
+                               }
+                       }
+               }
+
+               if (matching_attr) {
+                       GstColorBalanceChannel *channel;
+                       channel = g_object_new (GST_TYPE_COLOR_BALANCE_CHANNEL, NULL);
+                       channel->label = g_strdup (channels[i]);
+                       channel->min_value = matching_attr->min_value;
+                       channel->max_value = matching_attr->max_value;
+
+                       xcontext->channels_list = g_list_append (xcontext->channels_list, channel);
+
+                       /* If the colorbalance settings have not been touched we get Xv values
+                               as defaults and update our internal variables */
+                       if (!evaspixmapsink->cb_changed) {
+                               gint val;
+                               XvGetPortAttribute (xcontext->disp, xcontext->xv_port_id, prop_atom, &val);
+                               /* Normalize val to [-1000, 1000] */
+                               val = floor (0.5 + -1000 + 2000 * (val - channel->min_value) /  (double) (channel->max_value - channel->min_value));
+
+                               if (!g_ascii_strcasecmp (channels[i], "XV_HUE")) {
+                                       evaspixmapsink->hue = val;
+                               } else if (!g_ascii_strcasecmp (channels[i], "XV_SATURATION")) {
+                                       evaspixmapsink->saturation = val;
+                               } else if (!g_ascii_strcasecmp (channels[i], "XV_BRIGHTNESS")) {
+                                       evaspixmapsink->brightness = val;
+                               } else if (!g_ascii_strcasecmp (channels[i], "XV_CONTRAST")) {
+                                       evaspixmapsink->contrast = val;
+                               }
+                       }
+               }
+       }
+
+       if (xv_attr) {
+               XFree (xv_attr);
+       }
+
+       g_mutex_unlock (evaspixmapsink->x_lock);
+
+       return xcontext;
+}
+
+/* This function cleans the X context. Closing the Display, releasing the XV
+   port and unrefing the caps for supported formats. */
+static void
+gst_evaspixmapsink_xcontext_clear (GstEvasPixmapSink *evaspixmapsink)
+{
+  GList *formats_list, *channels_list;
+  GstXContext *xcontext;
+  gint i = 0;
+
+  g_return_if_fail (GST_IS_EVASPIXMAPSINK (evaspixmapsink));
+
+  GST_OBJECT_LOCK (evaspixmapsink);
+  if (evaspixmapsink->xcontext == NULL) {
+    GST_OBJECT_UNLOCK (evaspixmapsink);
+    return;
+  }
+
+  /* Take the XContext from the sink and clean it up */
+  xcontext = evaspixmapsink->xcontext;
+  evaspixmapsink->xcontext = NULL;
+
+  GST_OBJECT_UNLOCK (evaspixmapsink);
+
+  formats_list = xcontext->formats_list;
+
+  while (formats_list) {
+    GstEvasPixmapFormat *format = formats_list->data;
+
+    gst_caps_unref (format->caps);
+    g_free (format);
+    formats_list = g_list_next (formats_list);
+  }
+
+  if (xcontext->formats_list)
+    g_list_free (xcontext->formats_list);
+
+  channels_list = xcontext->channels_list;
+
+  while (channels_list) {
+    GstColorBalanceChannel *channel = channels_list->data;
+
+    g_object_unref (channel);
+    channels_list = g_list_next (channels_list);
+  }
+
+  if (xcontext->channels_list)
+    g_list_free (xcontext->channels_list);
+
+  gst_caps_unref (xcontext->caps);
+
+  for (i = 0; i < xcontext->nb_adaptors; i++) {
+    g_free (xcontext->adaptors[i]);
+  }
+
+  g_free (xcontext->adaptors);
+
+  g_free (xcontext->par);
+
+  g_mutex_lock (evaspixmapsink->x_lock);
+
+  GST_DEBUG_OBJECT (evaspixmapsink,"Closing display and freeing X Context");
+
+  XvUngrabPort (xcontext->disp, xcontext->xv_port_id, 0);
+
+  XCloseDisplay (xcontext->disp);
+
+  g_mutex_unlock (evaspixmapsink->x_lock);
+
+  g_free (xcontext);
+}
+
+/* Element stuff */
+
+/* This function tries to get a format matching with a given caps in the
+   supported list of formats we generated in gst_evaspixmapsink_get_xv_support */
+static gint
+gst_evaspixmapsink_get_format_from_caps (GstEvasPixmapSink *evaspixmapsink, GstCaps *caps)
+{
+  GList *list = NULL;
+
+  g_return_val_if_fail (GST_IS_EVASPIXMAPSINK (evaspixmapsink), 0);
+
+  list = evaspixmapsink->xcontext->formats_list;
+
+  while (list) {
+    GstEvasPixmapFormat *format = list->data;
+
+    if (format) {
+      if (gst_caps_can_intersect (caps, format->caps)) {
+        return format->format;
+      }
+    }
+    list = g_list_next (list);
+  }
+
+  return -1;
+}
+
+static GstCaps *
+gst_evaspixmapsink_getcaps (GstBaseSink *bsink)
+{
+  GstEvasPixmapSink *evaspixmapsink;
+
+  evaspixmapsink = GST_EVASPIXMAPSINK (bsink);
+
+  if (evaspixmapsink->xcontext)
+    return gst_caps_ref (evaspixmapsink->xcontext->caps);
+
+  return
+      gst_caps_copy (gst_pad_get_pad_template_caps (GST_VIDEO_SINK_PAD
+          (evaspixmapsink)));
+}
+
+static gboolean
+gst_evaspixmapsink_setcaps (GstBaseSink *bsink, GstCaps *caps)
+{
+       GstEvasPixmapSink *evaspixmapsink;
+       GstStructure *structure;
+       guint32 im_format = 0;
+       gboolean ret;
+       gint video_width, video_height;
+       gint disp_x, disp_y;
+       gint disp_width, disp_height;
+       gint video_par_n, video_par_d;        /* video's PAR */
+       gint display_par_n, display_par_d;    /* display's PAR */
+       const GValue *caps_par;
+       const GValue *caps_disp_reg;
+       const GValue *fps;
+       guint num, den;
+#ifdef GST_EXT_XV_ENHANCEMENT
+       gboolean enable_last_buffer;
+#endif
+
+       evaspixmapsink = GST_EVASPIXMAPSINK (bsink);
+
+       GST_DEBUG_OBJECT (evaspixmapsink,"In setcaps. Possible caps %" GST_PTR_FORMAT ", setting caps %" GST_PTR_FORMAT, evaspixmapsink->xcontext->caps, caps);
+
+       if (!gst_caps_can_intersect (evaspixmapsink->xcontext->caps, caps)) {
+               goto incompatible_caps;
+       }
+
+       structure = gst_caps_get_structure (caps, 0);
+       ret = gst_structure_get_int (structure, "width", &video_width);
+       ret &= gst_structure_get_int (structure, "height", &video_height);
+       fps = gst_structure_get_value (structure, "framerate");
+       ret &= (fps != NULL);
+
+       if (!ret) {
+               goto incomplete_caps;
+       }
+
+#ifdef GST_EXT_XV_ENHANCEMENT
+       evaspixmapsink->aligned_width = video_width;
+       evaspixmapsink->aligned_height = video_height;
+
+       /* get enable-last-buffer */
+       g_object_get(G_OBJECT(evaspixmapsink), "enable-last-buffer", &enable_last_buffer, NULL);
+       GST_INFO_OBJECT (evaspixmapsink,"current enable-last-buffer : %d", enable_last_buffer);
+       /* flush if enable-last-buffer is TRUE */
+       if (enable_last_buffer) {
+               GST_INFO_OBJECT (evaspixmapsink,"flush last-buffer");
+               g_object_set(G_OBJECT(evaspixmapsink), "enable-last-buffer", FALSE, NULL);
+               g_object_set(G_OBJECT(evaspixmapsink), "enable-last-buffer", TRUE, NULL);
+       }
+#endif
+
+       evaspixmapsink->fps_n = gst_value_get_fraction_numerator (fps);
+       evaspixmapsink->fps_d = gst_value_get_fraction_denominator (fps);
+
+       evaspixmapsink->video_width = video_width;
+       evaspixmapsink->video_height = video_height;
+
+       im_format = gst_evaspixmapsink_get_format_from_caps (evaspixmapsink, caps);
+       if (im_format == -1) {
+               goto invalid_format;
+       }
+
+       /* get aspect ratio from caps if it's present, and
+       * convert video width and height to a display width and height
+       * using wd / hd = wv / hv * PARv / PARd */
+
+       /* get video's PAR */
+       caps_par = gst_structure_get_value (structure, "pixel-aspect-ratio");
+       if (caps_par) {
+               video_par_n = gst_value_get_fraction_numerator (caps_par);
+               video_par_d = gst_value_get_fraction_denominator (caps_par);
+       } else {
+               video_par_n = 1;
+               video_par_d = 1;
+       }
+       /* get display's PAR */
+       if (evaspixmapsink->par) {
+               display_par_n = gst_value_get_fraction_numerator (evaspixmapsink->par);
+               display_par_d = gst_value_get_fraction_denominator (evaspixmapsink->par);
+       } else {
+               display_par_n = 1;
+               display_par_d = 1;
+       }
+
+       /* get the display region */
+       caps_disp_reg = gst_structure_get_value (structure, "display-region");
+       if (caps_disp_reg) {
+               disp_x = g_value_get_int (gst_value_array_get_value (caps_disp_reg, 0));
+               disp_y = g_value_get_int (gst_value_array_get_value (caps_disp_reg, 1));
+               disp_width = g_value_get_int (gst_value_array_get_value (caps_disp_reg, 2));
+               disp_height = g_value_get_int (gst_value_array_get_value (caps_disp_reg, 3));
+       } else {
+               disp_x = disp_y = 0;
+               disp_width = video_width;
+               disp_height = video_height;
+       }
+
+       if (!gst_video_calculate_display_ratio (&num, &den, video_width, video_height, video_par_n, video_par_d, display_par_n, display_par_d)) {
+               goto no_disp_ratio;
+       }
+
+       evaspixmapsink->disp_x = disp_x;
+       evaspixmapsink->disp_y = disp_y;
+       evaspixmapsink->disp_width = disp_width;
+       evaspixmapsink->disp_height = disp_height;
+
+       GST_DEBUG_OBJECT (evaspixmapsink,"video width/height: %dx%d, calculated display ratio: %d/%d",  video_width, video_height, num, den);
+
+       /* now find a width x height that respects this display ratio.
+       * prefer those that have one of w/h the same as the incoming video
+       * using wd / hd = num / den */
+
+       /* start with same height, because of interlaced video */
+       /* check hd / den is an integer scale factor, and scale wd with the PAR */
+       if (video_height % den == 0) {
+               GST_DEBUG_OBJECT (evaspixmapsink,"keeping video height");
+               GST_VIDEO_SINK_WIDTH (evaspixmapsink) = (guint) gst_util_uint64_scale_int (video_height, num, den);
+               GST_VIDEO_SINK_HEIGHT (evaspixmapsink) = video_height;
+       } else if (video_width % num == 0) {
+               GST_DEBUG_OBJECT (evaspixmapsink,"keeping video width");
+               GST_VIDEO_SINK_WIDTH (evaspixmapsink) = video_width;
+               GST_VIDEO_SINK_HEIGHT (evaspixmapsink) = (guint) gst_util_uint64_scale_int (video_width, den, num);
+       } else {
+               GST_DEBUG_OBJECT (evaspixmapsink,"approximating while keeping video height");
+               GST_VIDEO_SINK_WIDTH (evaspixmapsink) = (guint) gst_util_uint64_scale_int (video_height, num, den);
+               GST_VIDEO_SINK_HEIGHT (evaspixmapsink) = video_height;
+       }
+       GST_DEBUG_OBJECT (evaspixmapsink,"scaling to %dx%d", GST_VIDEO_SINK_WIDTH (evaspixmapsink), GST_VIDEO_SINK_HEIGHT (evaspixmapsink));
+
+       /* Creating our window and our image with the display size in pixels */
+       if (GST_VIDEO_SINK_WIDTH (evaspixmapsink) <= 0 || GST_VIDEO_SINK_HEIGHT (evaspixmapsink) <= 0) {
+               goto no_display_size;
+       }
+
+       g_mutex_lock (evaspixmapsink->flow_lock);
+
+       /* We renew our evaspixmap buffer only if size or format changed;
+       * the evaspixmap buffer is the same size as the video pixel size */
+       if ((evaspixmapsink->evas_pixmap_buf) && ((im_format != evaspixmapsink->evas_pixmap_buf->im_format)
+               || (video_width != evaspixmapsink->evas_pixmap_buf->width) || (video_height != evaspixmapsink->evas_pixmap_buf->height))) {
+               GST_DEBUG_OBJECT (evaspixmapsink,"old format %" GST_FOURCC_FORMAT ", new format %" GST_FOURCC_FORMAT,
+                               GST_FOURCC_ARGS (evaspixmapsink->evas_pixmap_buf->im_format), GST_FOURCC_ARGS (im_format));
+               GST_DEBUG_OBJECT (evaspixmapsink,"renewing evaspixmap buffer");
+               gst_buffer_unref (GST_BUFFER (evaspixmapsink->evas_pixmap_buf));
+               evaspixmapsink->evas_pixmap_buf = NULL;
+       }
+
+       g_mutex_unlock (evaspixmapsink->flow_lock);
+
+       if (evaspixmapsink->eo) {
+               if (!gst_evaspixmapsink_xpixmap_link (evaspixmapsink)) {
+                       GST_ERROR_OBJECT (evaspixmapsink,"link evas image object with pixmap failed...");
+                       return FALSE;
+               } else {
+                       gst_evaspixmapsink_manage_event_thread (evaspixmapsink);
+               }
+       } else {
+               GST_ERROR_OBJECT (evaspixmapsink,"setcaps success, but there is no evas image object..");
+               return FALSE;
+       }
+
+       return TRUE;
+
+       /* ERRORS */
+       incompatible_caps:
+       {
+               GST_ERROR_OBJECT (evaspixmapsink,"caps incompatible");
+               return FALSE;
+       }
+       incomplete_caps:
+       {
+               GST_DEBUG_OBJECT (evaspixmapsink,"Failed to retrieve either width, ""height or framerate from intersected caps");
+               return FALSE;
+       }
+       invalid_format:
+       {
+               GST_DEBUG_OBJECT (evaspixmapsink,"Could not locate image format from caps %" GST_PTR_FORMAT, caps);
+               return FALSE;
+       }
+       no_disp_ratio:
+       {
+               GST_ELEMENT_ERROR (evaspixmapsink, CORE, NEGOTIATION, (NULL), ("Error calculating the output display ratio of the video."));
+               return FALSE;
+       }
+       no_display_size:
+       {
+               GST_ELEMENT_ERROR (evaspixmapsink, CORE, NEGOTIATION, (NULL), ("Error calculating the output display ratio of the video."));
+               return FALSE;
+       }
+}
+
+static GstStateChangeReturn
+gst_evaspixmapsink_change_state (GstElement *element, GstStateChange transition)
+{
+       GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
+       GstEvasPixmapSink *evaspixmapsink;
+
+       evaspixmapsink = GST_EVASPIXMAPSINK (element);
+
+       switch (transition) {
+       case GST_STATE_CHANGE_NULL_TO_READY:
+               GST_DEBUG_OBJECT (evaspixmapsink,"GST_STATE_CHANGE_NULL_TO_READY");
+
+               /* open drm to use gem */
+               if (drm_init(evaspixmapsink)) {
+                       GST_ERROR_OBJECT (evaspixmapsink,"drm_init() failure");
+                       return GST_STATE_CHANGE_FAILURE;
+               }
+
+               /* check if there exist evas image object, need to write code related to making internal evas image object */
+               if (!is_evas_image_object (evaspixmapsink->eo)) {
+                       GST_ERROR_OBJECT (evaspixmapsink,"There is no evas image object..");
+                       return GST_STATE_CHANGE_FAILURE;
+               }
+
+               /* Set xcontext and display */
+               if (!evaspixmapsink->xcontext) {
+                       evaspixmapsink->xcontext = gst_evaspixmapsink_xcontext_get (evaspixmapsink);
+                       if (!evaspixmapsink->xcontext) {
+                               GST_ERROR_OBJECT (evaspixmapsink,"could not get xcontext..");
+                               return GST_STATE_CHANGE_FAILURE;
+                       }
+               }
+
+               /* update object's par with calculated one if not set yet */
+               if (!evaspixmapsink->par) {
+                       evaspixmapsink->par = g_new0 (GValue, 1);
+                       gst_value_init_and_copy (evaspixmapsink->par, evaspixmapsink->xcontext->par);
+                       GST_DEBUG_OBJECT (evaspixmapsink,"set calculated PAR on object's PAR");
+               }
+
+               /* call XSynchronize with the current value of synchronous */
+               GST_DEBUG_OBJECT (evaspixmapsink,"XSynchronize called with %s", evaspixmapsink->synchronous ? "TRUE" : "FALSE");
+               XSynchronize (evaspixmapsink->xcontext->disp, evaspixmapsink->synchronous);
+               gst_evaspixmapsink_update_colorbalance (evaspixmapsink);
+               break;
+
+       case GST_STATE_CHANGE_READY_TO_PAUSED:
+               GST_DEBUG_OBJECT (evaspixmapsink,"GST_STATE_CHANGE_READY_TO_PAUSED");
+               break;
+
+       case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
+               GST_DEBUG_OBJECT (evaspixmapsink,"GST_STATE_CHANGE_PAUSED_TO_PLAYING");
+               break;
+
+       default:
+               break;
+       }
+
+       ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
+
+       switch (transition) {
+       case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
+               GST_DEBUG_OBJECT (evaspixmapsink,"GST_STATE_CHANGE_PLAYING_TO_PAUSED");
+               break;
+
+       case GST_STATE_CHANGE_PAUSED_TO_READY:
+               GST_DEBUG_OBJECT (evaspixmapsink,"GST_STATE_CHANGE_PAUSED_TO_READY");
+               evaspixmapsink->fps_n = 0;
+               evaspixmapsink->fps_d = 1;
+               GST_VIDEO_SINK_WIDTH (evaspixmapsink) = 0;
+               GST_VIDEO_SINK_HEIGHT (evaspixmapsink) = 0;
+               break;
+
+       case GST_STATE_CHANGE_READY_TO_NULL:
+               GST_DEBUG_OBJECT (evaspixmapsink,"GST_STATE_CHANGE_READY_TO_NULL");
+               gst_evaspixmapsink_reset (evaspixmapsink);
+               /* close drm */
+               drm_fini(evaspixmapsink);
+               break;
+
+       default:
+               break;
+       }
+       return ret;
+}
+
+static void
+gst_evaspixmapsink_get_times (GstBaseSink *bsink, GstBuffer *buf, GstClockTime *start, GstClockTime *end)
+{
+  GstEvasPixmapSink *evaspixmapsink;
+
+  evaspixmapsink = GST_EVASPIXMAPSINK (bsink);
+
+  if (GST_BUFFER_TIMESTAMP_IS_VALID (buf)) {
+    *start = GST_BUFFER_TIMESTAMP (buf);
+    if (GST_BUFFER_DURATION_IS_VALID (buf)) {
+      *end = *start + GST_BUFFER_DURATION (buf);
+    } else {
+      if (evaspixmapsink->fps_n > 0) {
+        *end = *start +
+            gst_util_uint64_scale_int (GST_SECOND, evaspixmapsink->fps_d,
+            evaspixmapsink->fps_n);
+      }
+    }
+  }
+}
+
+static GstFlowReturn
+gst_evaspixmapsink_show_frame (GstVideoSink *vsink, GstBuffer *buf)
+{
+       GstEvasPixmapSink *evaspixmapsink;
+#ifdef GST_EXT_XV_ENHANCEMENT
+       XV_PUTIMAGE_DATA_PTR img_data = NULL;
+       SCMN_IMGB *scmn_imgb = NULL;
+       gint format = 0;
+#endif
+       evaspixmapsink = GST_EVASPIXMAPSINK (vsink);
+
+#ifdef GST_EXT_XV_ENHANCEMENT
+       if( evaspixmapsink->stop_video ) {
+               GST_INFO_OBJECT (evaspixmapsink, "Stop video is TRUE. so skip show frame..." );
+               return GST_FLOW_OK;
+       }
+#endif
+
+       if (!evaspixmapsink->evas_pixmap_buf) {
+               GST_DEBUG_OBJECT (evaspixmapsink,"creating our evaspixmap buffer");
+#ifdef GST_EXT_XV_ENHANCEMENT
+               format = gst_evaspixmapsink_get_format_from_caps(evaspixmapsink, GST_BUFFER_CAPS(buf));
+               switch (format) {
+               case GST_MAKE_FOURCC('S', 'T', '1', '2'):
+               case GST_MAKE_FOURCC('S', 'N', '1', '2'):
+               case GST_MAKE_FOURCC('S', '4', '2', '0'):
+               case GST_MAKE_FOURCC('S', 'U', 'Y', '2'):
+               case GST_MAKE_FOURCC('S', 'U', 'Y', 'V'):
+               case GST_MAKE_FOURCC('S', 'Y', 'V', 'Y'):
+                       scmn_imgb = (SCMN_IMGB *)GST_BUFFER_MALLOCDATA(buf);
+                       if(scmn_imgb == NULL) {
+                               GST_DEBUG_OBJECT (evaspixmapsink, "scmn_imgb is NULL. Skip buffer put..." );
+                               return GST_FLOW_OK;
+                       }
+                        /* skip buffer if aligned size is smaller than size of caps */
+                       if (scmn_imgb->s[0] < evaspixmapsink->video_width || scmn_imgb->e[0] < evaspixmapsink->video_height) {
+                               GST_WARNING_OBJECT (evaspixmapsink,"invalid size[caps:%dx%d,aligned:%dx%d]. Skip this buffer...",
+                                               evaspixmapsink->video_width, evaspixmapsink->video_height, scmn_imgb->s[0], scmn_imgb->e[0]);
+                               return GST_FLOW_OK;
+                       }
+                       evaspixmapsink->aligned_width = scmn_imgb->s[0];
+                       evaspixmapsink->aligned_height = scmn_imgb->e[0];
+                       GST_DEBUG_OBJECT (evaspixmapsink,"video width,height[%dx%d]",evaspixmapsink->video_width, evaspixmapsink->video_height);
+                       GST_INFO_OBJECT (evaspixmapsink,"Use aligned width,height[%dx%d]",evaspixmapsink->aligned_width, evaspixmapsink->aligned_height);
+                       break;
+               default:
+                       GST_INFO_OBJECT (evaspixmapsink,"Use original width,height of caps");
+                       break;
+               }
+#endif
+               evaspixmapsink->evas_pixmap_buf = gst_evaspixmap_buffer_new (evaspixmapsink, GST_BUFFER_CAPS (buf));
+               if (!evaspixmapsink->evas_pixmap_buf) {
+                       /* The create method should have posted an informative error */
+                       goto no_image;
+               }
+               if (evaspixmapsink->evas_pixmap_buf->size < GST_BUFFER_SIZE (buf)) {
+                       GST_ELEMENT_ERROR (evaspixmapsink, RESOURCE, WRITE, ("Failed to create output image buffer of %dx%d pixels",    evaspixmapsink->evas_pixmap_buf->width, evaspixmapsink->evas_pixmap_buf->height),("XServer allocated buffer size did not match input buffer"));
+                       gst_evaspixmap_buffer_destroy (evaspixmapsink->evas_pixmap_buf);
+                       evaspixmapsink->evas_pixmap_buf = NULL;
+                       goto no_image;
+               }
+       }
+
+#ifdef GST_EXT_XV_ENHANCEMENT
+       switch (evaspixmapsink->evas_pixmap_buf->im_format) {
+       /* Cases for specified formats of Samsung extension */
+       case GST_MAKE_FOURCC('S', 'T', '1', '2'):
+       case GST_MAKE_FOURCC('S', 'N', '1', '2'):
+       case GST_MAKE_FOURCC('S', '4', '2', '0'):
+       case GST_MAKE_FOURCC('S', 'U', 'Y', '2'):
+       case GST_MAKE_FOURCC('S', 'U', 'Y', 'V'):
+       case GST_MAKE_FOURCC('S', 'Y', 'V', 'Y'):
+       case GST_MAKE_FOURCC('I', 'T', 'L', 'V'):
+       {
+               GST_DEBUG_OBJECT (evaspixmapsink,"Samsung extension display format activated. fourcc:%d", evaspixmapsink->evas_pixmap_buf->im_format);
+
+               if (evaspixmapsink->evas_pixmap_buf->xvimage->data) {
+                       img_data = (XV_PUTIMAGE_DATA_PTR) evaspixmapsink->evas_pixmap_buf->xvimage->data;
+                       XV_PUTIMAGE_INIT_DATA(img_data);
+                       scmn_imgb = (SCMN_IMGB *)GST_BUFFER_MALLOCDATA(buf);
+                       if (scmn_imgb == NULL) {
+                               GST_DEBUG_OBJECT (evaspixmapsink, "scmn_imgb is NULL. Skip buffer put..." );
+                               return GST_FLOW_OK;
+                       }
+
+                       if (scmn_imgb->buf_share_method == BUF_SHARE_METHOD_PADDR) {
+                               img_data->YBuf = (unsigned int)scmn_imgb->p[0];
+                               img_data->CbBuf = (unsigned int)scmn_imgb->p[1];
+                               img_data->CrBuf = (unsigned int)scmn_imgb->p[2];
+                               img_data->BufType = XV_BUF_TYPE_LEGACY;
+                               if (!img_data->YBuf) {
+                                       GST_WARNING_OBJECT (evaspixmapsink, "img_data->YBuf is NULL. skip buffer put..." );
+                                       return GST_FLOW_OK;
+                               }
+                       } else { /* BUF_SHARE_METHOD_FD */
+                               /* convert dma-buf fd into drm gem name */
+                               img_data->YBuf = drm_convert_dmabuf_gemname(evaspixmapsink, (int)scmn_imgb->dma_buf_fd[0]);
+                               img_data->CbBuf = drm_convert_dmabuf_gemname(evaspixmapsink, (int)scmn_imgb->dma_buf_fd[1]);
+                               img_data->CrBuf = drm_convert_dmabuf_gemname(evaspixmapsink, (int)scmn_imgb->dma_buf_fd[2]);
+                               img_data->BufType = XV_BUF_TYPE_DMABUF;
+                               if (!img_data->YBuf) {
+                                       GST_WARNING_OBJECT (evaspixmapsink, "img_data->YBuf is NULL. skip buffer put..." );
+                                       return GST_FLOW_OK;
+                               }
+                       }
+                       GST_LOG_OBJECT(evaspixmapsink, "YBuf[%d], CbBuf[%d], CrBuf[%d]",
+                                       img_data->YBuf, img_data->CbBuf, img_data->CrBuf );
+               } else {
+                       GST_WARNING_OBJECT (evaspixmapsink, "xvimage->data is NULL. skip buffer put..." );
+                       return GST_FLOW_OK;
+               }
+               break;
+       }
+       default:
+       {
+               GST_DEBUG_OBJECT (evaspixmapsink,"Normal format activated. fourcc = %d", evaspixmapsink->evas_pixmap_buf->im_format);
+               __ta__("evaspixmapsink memcpy in _show_frame", memcpy (evaspixmapsink->evas_pixmap_buf->xvimage->data, GST_BUFFER_DATA (buf),
+               MIN (GST_BUFFER_SIZE (buf), evaspixmapsink->evas_pixmap_buf->size)););
+               break;
+       }
+       }
+#else
+       __ta__("evaspixmapsink memcpy in _show_frame", memcpy (evaspixmapsink->evas_pixmap_buf->xvimage->data, GST_BUFFER_DATA (buf), MIN (GST_BUFFER_SIZE (buf), evaspixmapsink->evas_pixmap_buf->size)););
+#endif
+       if (!gst_evaspixmap_buffer_put (evaspixmapsink, evaspixmapsink->evas_pixmap_buf)) {
+               goto no_pixmap;
+       }
+
+       return GST_FLOW_OK;
+
+       /* ERRORS */
+       no_image:
+       {
+               /* No image available. That's very bad ! */
+               GST_WARNING_OBJECT (evaspixmapsink,"could not create image");
+               return GST_FLOW_ERROR;
+       }
+       no_pixmap:
+       {
+               /* No Pixmap available to put our image into */
+               GST_WARNING_OBJECT (evaspixmapsink,"could not output image - no pixmap");
+               return GST_FLOW_ERROR;
+       }
+}
+
+static gboolean
+gst_evaspixmapsink_event (GstBaseSink *sink, GstEvent *event)
+{
+       GstEvasPixmapSink *evaspixmapsink = GST_EVASPIXMAPSINK (sink);
+
+       switch (GST_EVENT_TYPE (event)) {
+       case GST_EVENT_FLUSH_START:
+               GST_DEBUG_OBJECT (evaspixmapsink,"GST_EVENT_FLUSH_START");
+               break;
+       case GST_EVENT_FLUSH_STOP:
+               GST_DEBUG_OBJECT (evaspixmapsink,"GST_EVENT_FLUSH_STOP");
+               break;
+       default:
+               break;
+       }
+       if (GST_BASE_SINK_CLASS (parent_class)->event) {
+               return GST_BASE_SINK_CLASS (parent_class)->event (sink, event);
+       } else {
+               return TRUE;
+       }
+}
+
+/* Interfaces stuff */
+
+static gboolean
+gst_evaspixmapsink_interface_supported (GstImplementsInterface *iface, GType type)
+{
+  g_assert (type == GST_TYPE_NAVIGATION || type == GST_TYPE_COLOR_BALANCE || type == GST_TYPE_PROPERTY_PROBE);
+  return TRUE;
+}
+
+static void
+gst_evaspixmapsink_interface_init (GstImplementsInterfaceClass *klass)
+{
+  klass->supported = gst_evaspixmapsink_interface_supported;
+}
+
+static void
+gst_evaspixmapsink_navigation_send_event (GstNavigation *navigation, GstStructure *structure)
+{
+  GstEvasPixmapSink *evaspixmapsink = GST_EVASPIXMAPSINK (navigation);
+  GstPad *peer;
+
+  if ((peer = gst_pad_get_peer (GST_VIDEO_SINK_PAD (evaspixmapsink)))) {
+    GstEvent *event;
+    GstVideoRectangle src, dst, result;
+    gdouble x, y, xscale = 1.0, yscale = 1.0;
+
+    event = gst_event_new_navigation (structure);
+
+    /* We take the flow_lock while we look at the window */
+    g_mutex_lock (evaspixmapsink->flow_lock);
+
+    if (!evaspixmapsink->xpixmap) {
+      g_mutex_unlock (evaspixmapsink->flow_lock);
+      return;
+    }
+
+    if (evaspixmapsink->keep_aspect) {
+      /* We get the frame position using the calculated geometry from _setcaps
+         that respect pixel aspect ratios */
+      src.w = GST_VIDEO_SINK_WIDTH (evaspixmapsink);
+      src.h = GST_VIDEO_SINK_HEIGHT (evaspixmapsink);
+      dst.w = evaspixmapsink->render_rect.w;
+      dst.h = evaspixmapsink->render_rect.h;
+
+      gst_video_sink_center_rect (src, dst, &result, TRUE);
+      result.x += evaspixmapsink->render_rect.x;
+      result.y += evaspixmapsink->render_rect.y;
+    } else {
+      memcpy (&result, &evaspixmapsink->render_rect, sizeof (GstVideoRectangle));
+    }
+
+    g_mutex_unlock (evaspixmapsink->flow_lock);
+
+    /* We calculate scaling using the original video frames geometry to include
+       pixel aspect ratio scaling. */
+    xscale = (gdouble) evaspixmapsink->video_width / result.w;
+    yscale = (gdouble) evaspixmapsink->video_height / result.h;
+
+    /* Converting pointer coordinates to the non scaled geometry */
+    if (gst_structure_get_double (structure, "pointer_x", &x)) {
+      x = MIN (x, result.x + result.w);
+      x = MAX (x - result.x, 0);
+      gst_structure_set (structure, "pointer_x", G_TYPE_DOUBLE,
+          (gdouble) x * xscale, NULL);
+    }
+    if (gst_structure_get_double (structure, "pointer_y", &y)) {
+      y = MIN (y, result.y + result.h);
+      y = MAX (y - result.y, 0);
+      gst_structure_set (structure, "pointer_y", G_TYPE_DOUBLE,
+          (gdouble) y * yscale, NULL);
+    }
+
+    gst_pad_send_event (peer, event);
+    gst_object_unref (peer);
+  }
+}
+
+static void
+gst_evaspixmapsink_navigation_init (GstNavigationInterface *iface)
+{
+  iface->send_event = gst_evaspixmapsink_navigation_send_event;
+}
+
+static const GList*
+gst_evaspixmapsink_colorbalance_list_channels (GstColorBalance *balance)
+{
+  GstEvasPixmapSink *evaspixmapsink = GST_EVASPIXMAPSINK (balance);
+
+  g_return_val_if_fail (GST_IS_EVASPIXMAPSINK (evaspixmapsink), NULL);
+
+  if (evaspixmapsink->xcontext)
+    return evaspixmapsink->xcontext->channels_list;
+  else
+    return NULL;
+}
+
+static void
+gst_evaspixmapsink_colorbalance_set_value (GstColorBalance *balance, GstColorBalanceChannel *channel, gint value)
+{
+  GstEvasPixmapSink *evaspixmapsink = GST_EVASPIXMAPSINK (balance);
+
+  g_return_if_fail (GST_IS_EVASPIXMAPSINK (evaspixmapsink));
+  g_return_if_fail (channel->label != NULL);
+
+  evaspixmapsink->cb_changed = TRUE;
+
+  /* Normalize val to [-1000, 1000] */
+  value = floor (0.5 + -1000 + 2000 * (value - channel->min_value) /
+      (double) (channel->max_value - channel->min_value));
+
+  if (g_ascii_strcasecmp (channel->label, "XV_HUE") == 0) {
+    evaspixmapsink->hue = value;
+  } else if (g_ascii_strcasecmp (channel->label, "XV_SATURATION") == 0) {
+    evaspixmapsink->saturation = value;
+  } else if (g_ascii_strcasecmp (channel->label, "XV_CONTRAST") == 0) {
+    evaspixmapsink->contrast = value;
+  } else if (g_ascii_strcasecmp (channel->label, "XV_BRIGHTNESS") == 0) {
+    evaspixmapsink->brightness = value;
+  } else {
+    g_warning ("got an unknown channel %s", channel->label);
+    return;
+  }
+
+  gst_evaspixmapsink_update_colorbalance (evaspixmapsink);
+}
+
+static gint
+gst_evaspixmapsink_colorbalance_get_value (GstColorBalance *balance, GstColorBalanceChannel *channel)
+{
+  GstEvasPixmapSink *evaspixmapsink = GST_EVASPIXMAPSINK (balance);
+  gint value = 0;
+
+  g_return_val_if_fail (GST_IS_EVASPIXMAPSINK (evaspixmapsink), 0);
+  g_return_val_if_fail (channel->label != NULL, 0);
+
+  if (g_ascii_strcasecmp (channel->label, "XV_HUE") == 0) {
+    value = evaspixmapsink->hue;
+  } else if (g_ascii_strcasecmp (channel->label, "XV_SATURATION") == 0) {
+    value = evaspixmapsink->saturation;
+  } else if (g_ascii_strcasecmp (channel->label, "XV_CONTRAST") == 0) {
+    value = evaspixmapsink->contrast;
+  } else if (g_ascii_strcasecmp (channel->label, "XV_BRIGHTNESS") == 0) {
+    value = evaspixmapsink->brightness;
+  } else {
+    g_warning ("got an unknown channel %s", channel->label);
+  }
+
+  /* Normalize val to [channel->min_value, channel->max_value] */
+  value = channel->min_value + (channel->max_value - channel->min_value) * (value + 1000) / 2000;
+
+  return value;
+}
+
+static void
+gst_evaspixmapsink_colorbalance_init (GstColorBalanceClass *iface)
+{
+  GST_COLOR_BALANCE_TYPE (iface) = GST_COLOR_BALANCE_HARDWARE;
+  iface->list_channels = gst_evaspixmapsink_colorbalance_list_channels;
+  iface->set_value = gst_evaspixmapsink_colorbalance_set_value;
+  iface->get_value = gst_evaspixmapsink_colorbalance_get_value;
+}
+
+static const GList *
+gst_evaspixmapsink_probe_get_properties (GstPropertyProbe *probe)
+{
+       GObjectClass *klass = G_OBJECT_GET_CLASS (probe);
+       static GList *list = NULL;
+
+       if (!list) {
+               list = g_list_append (NULL, g_object_class_find_property (klass, "device"));
+               list = g_list_append (list, g_object_class_find_property (klass, "autopaint-colorkey"));
+               list = g_list_append (list, g_object_class_find_property (klass, "double-buffer"));
+               list = g_list_append (list, g_object_class_find_property (klass, "colorkey"));
+       }
+
+       return list;
+}
+
+static void
+gst_evaspixmapsink_probe_probe_property (GstPropertyProbe *probe, guint prop_id, const GParamSpec *pspec)
+{
+  GstEvasPixmapSink *evaspixmapsink = GST_EVASPIXMAPSINK (probe);
+
+  switch (prop_id) {
+    case PROP_DEVICE:
+    case PROP_AUTOPAINT_COLORKEY:
+    case PROP_DOUBLE_BUFFER:
+    case PROP_COLORKEY:
+      GST_DEBUG_OBJECT (evaspixmapsink,"probing device list and get capabilities");
+      if (!evaspixmapsink->xcontext) {
+        GST_DEBUG_OBJECT (evaspixmapsink,"generating xcontext");
+        evaspixmapsink->xcontext = gst_evaspixmapsink_xcontext_get (evaspixmapsink);
+        if (!evaspixmapsink->xcontext) {
+          GST_ERROR_OBJECT (evaspixmapsink,"could not get xcontext..");
+        }
+      }
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (probe, prop_id, pspec);
+      break;
+  }
+}
+
+static gboolean
+gst_evaspixmapsink_probe_needs_probe (GstPropertyProbe *probe, guint prop_id, const GParamSpec *pspec)
+{
+  GstEvasPixmapSink *evaspixmapsink = GST_EVASPIXMAPSINK (probe);
+  gboolean ret = FALSE;
+
+  switch (prop_id) {
+    case PROP_DEVICE:
+    case PROP_AUTOPAINT_COLORKEY:
+    case PROP_DOUBLE_BUFFER:
+    case PROP_COLORKEY:
+      if (evaspixmapsink->xcontext != NULL) {
+        ret = FALSE;
+      } else {
+        ret = TRUE;
+      }
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (probe, prop_id, pspec);
+      break;
+  }
+
+  return ret;
+}
+
+static GValueArray *
+gst_evaspixmapsink_probe_get_values (GstPropertyProbe *probe, guint prop_id, const GParamSpec *pspec)
+{
+  GstEvasPixmapSink *evaspixmapsink = GST_EVASPIXMAPSINK (probe);
+  GValueArray *array = NULL;
+
+  if (G_UNLIKELY (!evaspixmapsink->xcontext)) {
+    GST_WARNING_OBJECT (evaspixmapsink,"we don't have any xcontext, can't "
+        "get values");
+    goto beach;
+  }
+
+  switch (prop_id) {
+    case PROP_DEVICE:
+    {
+      guint i;
+      GValue value = { 0 };
+
+      array = g_value_array_new (evaspixmapsink->xcontext->nb_adaptors);
+      g_value_init (&value, G_TYPE_STRING);
+
+      for (i = 0; i < evaspixmapsink->xcontext->nb_adaptors; i++) {
+        gchar *adaptor_id_s = g_strdup_printf ("%u", i);
+
+        g_value_set_string (&value, adaptor_id_s);
+        g_value_array_append (array, &value);
+        g_free (adaptor_id_s);
+      }
+      g_value_unset (&value);
+      break;
+    }
+    case PROP_AUTOPAINT_COLORKEY:
+      if (evaspixmapsink->have_autopaint_colorkey) {
+        GValue value = { 0 };
+
+        array = g_value_array_new (2);
+        g_value_init (&value, G_TYPE_BOOLEAN);
+        g_value_set_boolean (&value, FALSE);
+        g_value_array_append (array, &value);
+        g_value_set_boolean (&value, TRUE);
+        g_value_array_append (array, &value);
+        g_value_unset (&value);
+      }
+      break;
+    case PROP_DOUBLE_BUFFER:
+      if (evaspixmapsink->have_double_buffer) {
+        GValue value = { 0 };
+
+        array = g_value_array_new (2);
+        g_value_init (&value, G_TYPE_BOOLEAN);
+        g_value_set_boolean (&value, FALSE);
+        g_value_array_append (array, &value);
+        g_value_set_boolean (&value, TRUE);
+        g_value_array_append (array, &value);
+        g_value_unset (&value);
+      }
+      break;
+    case PROP_COLORKEY:
+      if (evaspixmapsink->have_colorkey) {
+        GValue value = { 0 };
+
+        array = g_value_array_new (1);
+        g_value_init (&value, GST_TYPE_INT_RANGE);
+        gst_value_set_int_range (&value, 0, 0xffffff);
+        g_value_array_append (array, &value);
+        g_value_unset (&value);
+      }
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (probe, prop_id, pspec);
+      break;
+  }
+
+beach:
+  return array;
+}
+
+static void
+gst_evaspixmapsink_property_probe_interface_init (GstPropertyProbeInterface *iface)
+{
+       iface->get_properties = gst_evaspixmapsink_probe_get_properties;
+       iface->probe_property = gst_evaspixmapsink_probe_probe_property;
+       iface->needs_probe = gst_evaspixmapsink_probe_needs_probe;
+       iface->get_values = gst_evaspixmapsink_probe_get_values;
+}
+
+static gboolean
+gst_evaspixmapsink_xpixmap_link (GstEvasPixmapSink *evaspixmapsink)
+{
+       Display *dpy;
+       Pixmap *pixmap_id;
+       int evas_object_width = 0;
+       int evas_object_height = 0;
+       int pixmap_width = 0;
+       int pixmap_height = 0;
+       int xw = 0;
+       int xh = 0;
+
+       if (!evaspixmapsink) {
+               GST_ERROR_OBJECT (evaspixmapsink,"could not get evaspixmapsink..");
+               return FALSE;
+       }
+       g_mutex_lock (evaspixmapsink->flow_lock);
+
+       /* Set xcontext and display */
+       if (!evaspixmapsink->xcontext) {
+               GST_WARNING_OBJECT (evaspixmapsink,"there's no xcontext, try to get one..");
+               evaspixmapsink->xcontext = gst_evaspixmapsink_xcontext_get (evaspixmapsink);
+               if (!evaspixmapsink->xcontext) {
+                       GST_ERROR_OBJECT (evaspixmapsink,"could not get xcontext..");
+                       return FALSE;
+               }
+       }
+
+       dpy = evaspixmapsink->xcontext->disp;
+
+       /* Set evas image object size */
+       evas_object_geometry_get(evaspixmapsink->eo, NULL, NULL, &evas_object_width, &evas_object_height);
+       if (evaspixmapsink->use_origin_size || !evas_object_width || !evas_object_height) {
+               pixmap_width = evaspixmapsink->video_width;
+               pixmap_height = evaspixmapsink->video_height;
+               GST_INFO_OBJECT (evaspixmapsink,"set size to media src size(%dx%d)", pixmap_width, pixmap_height);
+       }
+
+       g_mutex_lock (evaspixmapsink->x_lock);
+       if (evaspixmapsink->use_origin_size || !evas_object_width || !evas_object_height) {
+               XvQueryBestSize(dpy, evaspixmapsink->xcontext->xv_port_id,0,0,0, pixmap_width, pixmap_height, &xw, &xh);
+               if (!evas_object_width || !evas_object_height) {
+                       evaspixmapsink->w = xw;
+                       evaspixmapsink->h = xh;
+               } else {
+                       evaspixmapsink->w = evas_object_width;
+                       evaspixmapsink->h = evas_object_height;
+               }
+               GST_DEBUG_OBJECT (evaspixmapsink,"XvQueryBestSize : xv_port_id(%d), w(%d),h(%d) => xw(%d),xh(%d)", evaspixmapsink->xcontext->xv_port_id, pixmap_width, pixmap_height, xw, xh);
+       } else {
+               XvQueryBestSize(dpy, evaspixmapsink->xcontext->xv_port_id,0,0,0, evas_object_width, evas_object_height, &xw, &xh);
+               GST_DEBUG_OBJECT (evaspixmapsink,"XvQueryBestSize : xv_port_id(%d), w(%d),h(%d) => xw(%d),xh(%d)", evaspixmapsink->xcontext->xv_port_id, evas_object_width, evas_object_height, xw, xh);
+               evaspixmapsink->w = xw;
+               evaspixmapsink->h = xh;
+       }
+       evas_object_image_size_set(evaspixmapsink->eo, evaspixmapsink->w, evaspixmapsink->h);
+
+       /* create xpixmap structure */
+       if (!evaspixmapsink->xpixmap) {
+               /* xpixmap can be created in this function only */
+               evaspixmapsink->xpixmap = g_new0 (GstXPixmap, 1);
+               if(!evaspixmapsink->xpixmap) {
+                       GST_ERROR_OBJECT (evaspixmapsink,"xpixmap is not valid..");
+                       goto GO_OUT_OF_FUNC;
+               }
+       }
+
+       /* create pixmap */
+       if (!xw || !xh) {
+               GST_WARNING_OBJECT (evaspixmapsink,"skip creating pixmap..xw(%d),xh(%d)",xw,xh);
+               goto GO_OUT_OF_FUNC;
+       } else {
+               pixmap_id = XCreatePixmap(dpy, DefaultRootWindow(dpy), xw, xh, DefaultDepth(dpy, DefaultScreen(dpy)));
+               if ( (int)pixmap_id == BadAlloc || (int)pixmap_id == BadDrawable || (int)pixmap_id == BadValue ) {
+                       GST_ERROR_OBJECT (evaspixmapsink,"pixmap allocation error..");
+                       goto GO_OUT_OF_FUNC;
+               }
+               GST_DEBUG_OBJECT (evaspixmapsink,"evas_object_width(%d),evas_object_height(%d),pixmap:%d,depth:%d",
+                       evas_object_width,evas_object_height,pixmap_id,DefaultDepth(dpy, DefaultScreen(dpy)));
+       }
+
+       if (evaspixmapsink->xpixmap->pixmap && pixmap_id != evaspixmapsink->xpixmap->pixmap) {
+               /* If we reset another pixmap, do below */
+               GST_DEBUG_OBJECT (evaspixmapsink,"destroy former pixmap(%d)",evaspixmapsink->xpixmap->pixmap);
+               if (evaspixmapsink->eo) {
+                       evas_object_image_native_surface_set(evaspixmapsink->eo, NULL);
+               }
+               g_mutex_unlock (evaspixmapsink->x_lock);
+               gst_evaspixmapsink_xpixmap_clear (evaspixmapsink, evaspixmapsink->xpixmap);
+               g_mutex_lock (evaspixmapsink->x_lock);
+               if(evaspixmapsink->xpixmap->pixmap) {
+                       XFreePixmap(evaspixmapsink->xcontext->disp, evaspixmapsink->xpixmap->pixmap);
+                       evaspixmapsink->xpixmap->pixmap = NULL;
+                       GST_DEBUG_OBJECT (evaspixmapsink,"Free pixmap");
+               }
+               XFreeGC (evaspixmapsink->xcontext->disp, evaspixmapsink->xpixmap->gc);
+               XSync (evaspixmapsink->xcontext->disp, FALSE);
+       }
+
+       /* Set pixmap id and create GC */
+       evaspixmapsink->xpixmap->pixmap = pixmap_id;
+       evaspixmapsink->xpixmap->gc = XCreateGC(dpy, evaspixmapsink->xpixmap->pixmap, 0,0);
+       XSetForeground(dpy, evaspixmapsink->xpixmap->gc,evaspixmapsink->xcontext->black);
+       XFillRectangle(dpy, evaspixmapsink->xpixmap->pixmap, evaspixmapsink->xpixmap->gc, 0, 0, xw, xh);
+       XSync(dpy, FALSE);
+
+       /* Create XDamage */
+       if (evaspixmapsink->damage) {
+               GST_DEBUG_OBJECT (evaspixmapsink,"destroy former damage(%d)",evaspixmapsink->damage);
+               XDamageDestroy(evaspixmapsink->xcontext->disp, evaspixmapsink->damage);
+               evaspixmapsink->damage = NULL;
+       }
+       evaspixmapsink->damage = XDamageCreate (dpy, evaspixmapsink->xpixmap->pixmap, XDamageReportRawRectangles);
+
+       /* Set flag for mapping evas object with xpixmap */
+       evaspixmapsink->do_link = TRUE;
+       ecore_pipe_write(evaspixmapsink->epipe, evaspixmapsink, sizeof(GstEvasPixmapSink));
+
+       gst_evaspixmapsink_update_colorbalance (evaspixmapsink);
+
+       g_mutex_unlock (evaspixmapsink->x_lock);
+       g_mutex_unlock (evaspixmapsink->flow_lock);
+
+       return TRUE;
+
+GO_OUT_OF_FUNC:
+       g_mutex_unlock (evaspixmapsink->x_lock);
+       g_mutex_unlock (evaspixmapsink->flow_lock);
+       return FALSE;
+}
+
+static void
+gst_evaspixmapsink_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
+{
+       GstEvasPixmapSink *evaspixmapsink;
+       g_return_if_fail (GST_IS_EVASPIXMAPSINK (object));
+       evaspixmapsink = GST_EVASPIXMAPSINK (object);
+
+       Evas_Object *eo;
+
+       switch (prop_id) {
+       case PROP_HUE:
+               evaspixmapsink->hue = g_value_get_int (value);
+               evaspixmapsink->cb_changed = TRUE;
+               gst_evaspixmapsink_update_colorbalance (evaspixmapsink);
+               break;
+       case PROP_CONTRAST:
+               evaspixmapsink->contrast = g_value_get_int (value);
+               evaspixmapsink->cb_changed = TRUE;
+               gst_evaspixmapsink_update_colorbalance (evaspixmapsink);
+               break;
+       case PROP_BRIGHTNESS:
+               evaspixmapsink->brightness = g_value_get_int (value);
+               evaspixmapsink->cb_changed = TRUE;
+               gst_evaspixmapsink_update_colorbalance (evaspixmapsink);
+               break;
+       case PROP_SATURATION:
+               evaspixmapsink->saturation = g_value_get_int (value);
+               evaspixmapsink->cb_changed = TRUE;
+               gst_evaspixmapsink_update_colorbalance (evaspixmapsink);
+               break;
+       case PROP_DISPLAY:
+               evaspixmapsink->display_name = g_strdup (g_value_get_string (value));
+               break;
+       case PROP_SYNCHRONOUS:
+               evaspixmapsink->synchronous = g_value_get_boolean (value);
+               if (evaspixmapsink->xcontext) {
+                       XSynchronize (evaspixmapsink->xcontext->disp, evaspixmapsink->synchronous);
+                       GST_DEBUG_OBJECT (evaspixmapsink,"XSynchronize called with %s", evaspixmapsink->synchronous ? "TRUE" : "FALSE");
+               }
+               break;
+       case PROP_PIXEL_ASPECT_RATIO:
+               g_free (evaspixmapsink->par);
+               evaspixmapsink->par = g_new0 (GValue, 1);
+               g_value_init (evaspixmapsink->par, GST_TYPE_FRACTION);
+               if (!g_value_transform (value, evaspixmapsink->par)) {
+                       g_warning ("Could not transform string to aspect ratio");
+                       gst_value_set_fraction (evaspixmapsink->par, 1, 1);
+               }
+               GST_DEBUG_OBJECT (evaspixmapsink,"set PAR to %d/%d", gst_value_get_fraction_numerator (evaspixmapsink->par), gst_value_get_fraction_denominator (evaspixmapsink->par));
+               break;
+       case PROP_FORCE_ASPECT_RATIO:
+               evaspixmapsink->keep_aspect = g_value_get_boolean (value);
+               break;
+       case PROP_DEVICE:
+               evaspixmapsink->adaptor_no = atoi (g_value_get_string (value));
+               break;
+       case PROP_DOUBLE_BUFFER:
+               evaspixmapsink->double_buffer = g_value_get_boolean (value);
+               break;
+       case PROP_AUTOPAINT_COLORKEY:
+               evaspixmapsink->autopaint_colorkey = g_value_get_boolean (value);
+               break;
+       case PROP_COLORKEY:
+               evaspixmapsink->colorkey = g_value_get_int (value);
+               break;
+       case PROP_PIXMAP_WIDTH:
+               if (evaspixmapsink->xpixmap) {
+                       evaspixmapsink->xpixmap->width = g_value_get_uint64 (value);
+                       /* To do : code related to pixmap re-link */
+               }
+               break;
+       case PROP_PIXMAP_HEIGHT:
+               if (evaspixmapsink->xpixmap) {
+                       evaspixmapsink->xpixmap->height = g_value_get_uint64 (value);
+                       /* To do : code related to pixmap re-link */
+               }
+               break;
+#ifdef GST_EXT_XV_ENHANCEMENT
+       case PROP_DISPLAY_GEOMETRY_METHOD:
+               evaspixmapsink->display_geometry_method = g_value_get_enum (value);
+               GST_INFO_OBJECT (evaspixmapsink,"Overlay geometry method update, display_geometry_method(%d)",evaspixmapsink->display_geometry_method);
+               if( evaspixmapsink->display_geometry_method != DISP_GEO_METHOD_FULL_SCREEN &&
+                         evaspixmapsink->display_geometry_method != DISP_GEO_METHOD_CROPPED_FULL_SCREEN ) {
+                       if( evaspixmapsink->xcontext && evaspixmapsink->xpixmap ) {
+                               g_mutex_lock( evaspixmapsink->flow_lock );
+                               gst_evaspixmapsink_xpixmap_clear (evaspixmapsink, evaspixmapsink->xpixmap);
+                               g_mutex_unlock( evaspixmapsink->flow_lock );
+                       }
+               }
+               if (evaspixmapsink->xcontext) {
+                       gst_evaspixmap_buffer_put (evaspixmapsink, evaspixmapsink->evas_pixmap_buf);
+               }
+               break;
+       case PROP_DST_ROI_X:
+               evaspixmapsink->dst_roi.x = g_value_get_int (value);
+               GST_INFO_OBJECT (evaspixmapsink, "ROI_X(%d)",evaspixmapsink->dst_roi.x );
+               break;
+       case PROP_DST_ROI_Y:
+               evaspixmapsink->dst_roi.y = g_value_get_int (value);
+               GST_INFO_OBJECT (evaspixmapsink, "ROI_Y(%d)",evaspixmapsink->dst_roi.y );
+               break;
+       case PROP_DST_ROI_W:
+               evaspixmapsink->dst_roi.w = g_value_get_int (value);
+               GST_INFO_OBJECT (evaspixmapsink, "ROI_W(%d)",evaspixmapsink->dst_roi.w );
+               break;
+       case PROP_DST_ROI_H:
+               evaspixmapsink->dst_roi.h = g_value_get_int (value);
+               GST_INFO_OBJECT (evaspixmapsink, "ROI_H(%d)",evaspixmapsink->dst_roi.h );
+               break;
+       case PROP_STOP_VIDEO:
+               evaspixmapsink->stop_video = g_value_get_int (value);
+               g_mutex_lock( evaspixmapsink->flow_lock );
+               if( evaspixmapsink->stop_video ) {
+                       GST_INFO_OBJECT (evaspixmapsink, "XPixmap CLEAR when set video-stop property" );
+                       gst_evaspixmapsink_xpixmap_clear (evaspixmapsink, evaspixmapsink->xpixmap);
+               }
+               g_mutex_unlock( evaspixmapsink->flow_lock );
+               break;
+#endif
+       case PROP_EVAS_OBJECT:
+               eo = g_value_get_pointer (value);
+               if ( is_evas_image_object (eo)) {
+                       if (!evaspixmapsink->epipe) {
+                               evaspixmapsink->epipe = ecore_pipe_add (ecore_pipe_callback_handler, evaspixmapsink);
+                               if (!evaspixmapsink->epipe) {
+                                       GST_ERROR_OBJECT (evaspixmapsink,"Cannot set evas-object property: ecore_pipe_add() failed");
+                                       break;
+                               }
+                       }
+                       if (eo != evaspixmapsink->eo) {
+                               /* delete evas object callbacks registrated on a former evas image object */
+                               evas_object_event_callback_del (evaspixmapsink->eo, EVAS_CALLBACK_DEL, evas_callback_del_event);
+                               evas_object_event_callback_del (evaspixmapsink->eo, EVAS_CALLBACK_RESIZE, evas_callback_resize_event);
+                               if (evaspixmapsink->eo) {
+                                       if (!gst_evaspixmapsink_xpixmap_link(evaspixmapsink)) {
+                                               GST_WARNING_OBJECT (evaspixmapsink,"link evas image object with pixmap failed...");
+                                               return;
+                                       }
+                               }
+                               evaspixmapsink->eo = eo;
+                               /* add evas object callbacks on a new evas image object */
+                               evas_object_event_callback_add (evaspixmapsink->eo, EVAS_CALLBACK_DEL, evas_callback_del_event, evaspixmapsink);
+                               evas_object_event_callback_add (evaspixmapsink->eo, EVAS_CALLBACK_RESIZE, evas_callback_resize_event, evaspixmapsink);
+                               GST_INFO_OBJECT (evaspixmapsink,"Evas Image Object(%x) is set", evaspixmapsink->eo);
+                       }
+               } else {
+                       GST_ERROR_OBJECT (evaspixmapsink,"Cannot set evas-object property: value is not an evas image object");
+               }
+                 break;
+       case PROP_VISIBLE:
+               evaspixmapsink->visible = g_value_get_boolean (value);
+               if (evaspixmapsink->eo) {
+                       if (!evaspixmapsink->visible) {
+                               if ( evaspixmapsink->xcontext && evaspixmapsink->xpixmap ) {
+                                       g_mutex_lock( evaspixmapsink->flow_lock );
+                                       gst_evaspixmapsink_xpixmap_clear (evaspixmapsink, evaspixmapsink->xpixmap);
+                                       g_mutex_unlock( evaspixmapsink->flow_lock );
+                               }
+                               evas_object_hide(evaspixmapsink->eo);
+                               GST_INFO_OBJECT (evaspixmapsink,"object hide..");
+                       } else {
+                               evas_object_show(evaspixmapsink->eo);
+                               GST_INFO_OBJECT (evaspixmapsink,"object show..");
+                       }
+               } else {
+                       GST_WARNING_OBJECT (evaspixmapsink,"evas image object was not set");
+               }
+               break;
+       case PROP_ORIGIN_SIZE:
+               evaspixmapsink->use_origin_size = g_value_get_boolean (value);
+               GST_INFO_OBJECT (evaspixmapsink,"set origin-size (%d)",evaspixmapsink->use_origin_size);
+               if (evaspixmapsink->former_origin_size != evaspixmapsink->use_origin_size) {
+                       if (!gst_evaspixmapsink_xpixmap_link(evaspixmapsink)) {
+                               GST_WARNING_OBJECT (evaspixmapsink,"link evas image object with pixmap failed...");
+                       }
+                       evaspixmapsink->former_origin_size = evaspixmapsink->use_origin_size;
+               }
+               break;
+       default:
+               G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+               break;
+       }
+}
+
+static void
+gst_evaspixmapsink_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
+{
+       GstEvasPixmapSink *evaspixmapsink;
+
+       g_return_if_fail (GST_IS_EVASPIXMAPSINK (object));
+
+       evaspixmapsink = GST_EVASPIXMAPSINK (object);
+
+       switch (prop_id) {
+       case PROP_HUE:
+               g_value_set_int (value, evaspixmapsink->hue);
+               break;
+       case PROP_CONTRAST:
+               g_value_set_int (value, evaspixmapsink->contrast);
+               break;
+       case PROP_BRIGHTNESS:
+               g_value_set_int (value, evaspixmapsink->brightness);
+               break;
+       case PROP_SATURATION:
+               g_value_set_int (value, evaspixmapsink->saturation);
+               break;
+       case PROP_DISPLAY:
+               g_value_set_string (value, evaspixmapsink->display_name);
+               break;
+       case PROP_SYNCHRONOUS:
+               g_value_set_boolean (value, evaspixmapsink->synchronous);
+               break;
+       case PROP_PIXEL_ASPECT_RATIO:
+               if (evaspixmapsink->par) {
+                       if (!g_value_transform (evaspixmapsink->par, value)) {
+                               g_warning ("g_value_transform() failure");
+                       }
+               }
+               break;
+       case PROP_FORCE_ASPECT_RATIO:
+               g_value_set_boolean (value, evaspixmapsink->keep_aspect);
+               break;
+       case PROP_DEVICE:
+       {
+               char *adaptor_no_s = g_strdup_printf ("%u", evaspixmapsink->adaptor_no);
+               g_value_set_string (value, adaptor_no_s);
+               g_free (adaptor_no_s);
+               break;
+       }
+       case PROP_DEVICE_NAME:
+               if (evaspixmapsink->xcontext && evaspixmapsink->xcontext->adaptors) {
+                       g_value_set_string (value,
+                       evaspixmapsink->xcontext->adaptors[evaspixmapsink->adaptor_no]);
+               } else {
+                       g_value_set_string (value, NULL);
+               }
+               break;
+       case PROP_DOUBLE_BUFFER:
+               g_value_set_boolean (value, evaspixmapsink->double_buffer);
+               break;
+       case PROP_AUTOPAINT_COLORKEY:
+               g_value_set_boolean (value, evaspixmapsink->autopaint_colorkey);
+               break;
+       case PROP_COLORKEY:
+               g_value_set_int (value, evaspixmapsink->colorkey);
+               break;
+       case PROP_PIXMAP_WIDTH:
+               if (evaspixmapsink->xpixmap) {
+                       g_value_set_uint64 (value, evaspixmapsink->xpixmap->width);
+               } else {
+                       g_value_set_uint64 (value, 0);
+               }
+               break;
+       case PROP_PIXMAP_HEIGHT:
+               if (evaspixmapsink->xpixmap) {
+                       g_value_set_uint64 (value, evaspixmapsink->xpixmap->height);
+               } else {
+                       g_value_set_uint64 (value, 0);
+               }
+               break;
+#ifdef GST_EXT_XV_ENHANCEMENT
+       case PROP_DISPLAY_GEOMETRY_METHOD:
+               g_value_set_enum (value, evaspixmapsink->display_geometry_method);
+               break;
+       case PROP_DST_ROI_X:
+               g_value_set_int (value, evaspixmapsink->dst_roi.x);
+               break;
+       case PROP_DST_ROI_Y:
+               g_value_set_int (value, evaspixmapsink->dst_roi.y);
+               break;
+       case PROP_DST_ROI_W:
+               g_value_set_int (value, evaspixmapsink->dst_roi.w);
+               break;
+       case PROP_DST_ROI_H:
+               g_value_set_int (value, evaspixmapsink->dst_roi.h);
+               break;
+       case PROP_STOP_VIDEO:
+               g_value_set_int (value, evaspixmapsink->stop_video);
+               break;
+#endif
+       case PROP_EVAS_OBJECT:
+               g_value_set_pointer (value, evaspixmapsink->eo);
+               break;
+       case PROP_VISIBLE:
+               g_value_set_boolean (value, evaspixmapsink->visible);
+               break;
+       case PROP_ORIGIN_SIZE:
+               g_value_set_boolean (value, evaspixmapsink->use_origin_size);
+               break;
+       default:
+               G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+               break;
+  }
+}
+
+static void
+gst_evaspixmapsink_reset (GstEvasPixmapSink *evaspixmapsink)
+{
+       GST_DEBUG_OBJECT (evaspixmapsink,"[START]");
+
+       GThread *thread;
+       GST_OBJECT_LOCK (evaspixmapsink);
+       evaspixmapsink->running = FALSE;
+
+       /* grab thread and mark it as NULL */
+       thread = evaspixmapsink->event_thread;
+       evaspixmapsink->event_thread = NULL;
+       GST_OBJECT_UNLOCK (evaspixmapsink);
+
+       /* Wait for our event thread to finish before we clean up our stuff. */
+       if (thread) {
+               g_thread_join (thread);
+       }
+
+       if(evaspixmapsink->damage) {
+               XDamageDestroy(evaspixmapsink->xcontext->disp, evaspixmapsink->damage);
+               evaspixmapsink->damage = NULL;
+       }
+       if(evaspixmapsink->handler) {
+               ecore_event_handler_del (evaspixmapsink->handler);
+               evaspixmapsink->handler = NULL;
+       }
+
+       evas_object_event_callback_del (evaspixmapsink->eo, EVAS_CALLBACK_RESIZE, evas_callback_resize_event);
+       evas_object_event_callback_del (evaspixmapsink->eo, EVAS_CALLBACK_DEL, evas_callback_del_event);
+
+       if (evaspixmapsink->evas_pixmap_buf) {
+               gst_buffer_unref (GST_BUFFER_CAST (evaspixmapsink->evas_pixmap_buf));
+               evaspixmapsink->evas_pixmap_buf = NULL;
+       }
+       if (evaspixmapsink->xpixmap) {
+               gst_evaspixmapsink_xpixmap_clear (evaspixmapsink, evaspixmapsink->xpixmap);
+               gst_evaspixmapsink_xpixmap_destroy (evaspixmapsink, evaspixmapsink->xpixmap);
+               evaspixmapsink->xpixmap = NULL;
+               if (evaspixmapsink->eo) {
+                       evas_object_image_native_surface_set(evaspixmapsink->eo, NULL);
+                       evaspixmapsink->eo = NULL;
+               }
+       }
+       evaspixmapsink->render_rect.x = evaspixmapsink->render_rect.y =
+       evaspixmapsink->render_rect.w = evaspixmapsink->render_rect.h = 0;
+       evaspixmapsink->have_render_rect = FALSE;
+
+       gst_evaspixmapsink_xcontext_clear (evaspixmapsink);
+
+       GST_DEBUG_OBJECT (evaspixmapsink,"[END]");
+}
+
+/* Finalize is called only once, dispose can be called multiple times.
+ * We use mutexes and don't reset stuff to NULL here so let's register
+ * as a finalize. */
+static void
+gst_evaspixmapsink_finalize (GObject *object)
+{
+       GstEvasPixmapSink *evaspixmapsink;
+       evaspixmapsink = GST_EVASPIXMAPSINK (object);
+       GST_DEBUG_OBJECT (evaspixmapsink,"[START]");
+
+       if (evaspixmapsink->display_name) {
+               g_free (evaspixmapsink->display_name);
+               evaspixmapsink->display_name = NULL;
+       }
+       if (evaspixmapsink->par) {
+               g_free (evaspixmapsink->par);
+               evaspixmapsink->par = NULL;
+       }
+       if (evaspixmapsink->x_lock) {
+               g_mutex_free (evaspixmapsink->x_lock);
+               evaspixmapsink->x_lock = NULL;
+       }
+       if (evaspixmapsink->flow_lock) {
+               g_mutex_free (evaspixmapsink->flow_lock);
+               evaspixmapsink->flow_lock = NULL;
+       }
+       if (evaspixmapsink->epipe) {
+               ecore_pipe_del (evaspixmapsink->epipe);
+               evaspixmapsink->epipe = NULL;
+       }
+
+       GST_DEBUG_OBJECT (evaspixmapsink,"[END]");
+
+       G_OBJECT_CLASS (parent_class)->finalize (object);
+
+       MMTA_ACUM_ITEM_SHOW_RESULT_TO(MMTA_SHOW_FILE);
+       MMTA_RELEASE();
+}
+
+static void
+gst_evaspixmapsink_init (GstEvasPixmapSink *evaspixmapsink)
+{
+       evaspixmapsink->display_name = NULL;
+       evaspixmapsink->adaptor_no = 0;
+       evaspixmapsink->xcontext = NULL;
+       evaspixmapsink->xpixmap = NULL;
+       evaspixmapsink->evas_pixmap_buf = NULL;
+
+       evaspixmapsink->hue = evaspixmapsink->saturation = 0;
+       evaspixmapsink->contrast = evaspixmapsink->brightness = 0;
+       evaspixmapsink->cb_changed = FALSE;
+
+       evaspixmapsink->fps_n = 0;
+       evaspixmapsink->fps_d = 0;
+       evaspixmapsink->video_width = 0;
+       evaspixmapsink->video_height = 0;
+
+       evaspixmapsink->x_lock = g_mutex_new ();
+       evaspixmapsink->flow_lock = g_mutex_new ();
+
+       evaspixmapsink->synchronous = FALSE;
+       evaspixmapsink->double_buffer = TRUE;
+       evaspixmapsink->keep_aspect = FALSE;
+       evaspixmapsink->par = NULL;
+       evaspixmapsink->autopaint_colorkey = TRUE;
+       evaspixmapsink->running = FALSE;
+
+       /* on 16bit displays this becomes r,g,b = 1,2,3
+       * on 24bit displays this becomes r,g,b = 8,8,16
+       * as a port atom value
+       */
+       evaspixmapsink->colorkey = (8 << 16) | (8 << 8) | 16;
+
+#ifdef GST_EXT_XV_ENHANCEMENT
+       evaspixmapsink->display_geometry_method = DEF_DISPLAY_GEOMETRY_METHOD;
+       evaspixmapsink->dst_roi.x = 0;
+       evaspixmapsink->dst_roi.y = 0;
+       evaspixmapsink->dst_roi.w = 0;
+       evaspixmapsink->dst_roi.h = 0;
+       evaspixmapsink->scr_w = 0;
+       evaspixmapsink->scr_h = 0;
+       evaspixmapsink->aligned_width = 0;
+       evaspixmapsink->aligned_height = 0;
+#endif
+       evaspixmapsink->stop_video = FALSE;
+       evaspixmapsink->eo = NULL;
+       evaspixmapsink->epipe = NULL;
+       evaspixmapsink->do_link = FALSE;
+       evaspixmapsink->visible = TRUE;
+       evaspixmapsink->use_origin_size = FALSE;
+       evaspixmapsink->former_origin_size = FALSE;
+
+       MMTA_INIT();
+ }
+
+static void
+gst_evaspixmapsink_base_init (gpointer g_class)
+{
+  GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
+
+  gst_element_class_set_details_simple (element_class,
+      "EvasPixmapSink", "Sink/Video",
+      "evas image object videosink based on Xv extension", "Sangchul Lee <sc11.lee@samsung.com>");
+
+  gst_element_class_add_pad_template (element_class,
+      gst_static_pad_template_get (&gst_evaspixmapsink_sink_template_factory));
+}
+
+static void
+gst_evaspixmapsink_class_init (GstEvasPixmapSinkClass *klass)
+{
+  GObjectClass *gobject_class;
+  GstElementClass *gstelement_class;
+  GstBaseSinkClass *gstbasesink_class;
+  GstVideoSinkClass *videosink_class;
+
+  gobject_class = (GObjectClass *) klass;
+  gstelement_class = (GstElementClass *) klass;
+  gstbasesink_class = (GstBaseSinkClass *) klass;
+  videosink_class = (GstVideoSinkClass *) klass;
+
+  parent_class = g_type_class_peek_parent (klass);
+
+  gobject_class->set_property = gst_evaspixmapsink_set_property;
+  gobject_class->get_property = gst_evaspixmapsink_get_property;
+
+  g_object_class_install_property (gobject_class, PROP_CONTRAST,
+      g_param_spec_int ("contrast", "Contrast", "The contrast of the video",
+          -1000, 1000, 0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+  g_object_class_install_property (gobject_class, PROP_BRIGHTNESS,
+      g_param_spec_int ("brightness", "Brightness",
+          "The brightness of the video", -1000, 1000, 0,
+          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+  g_object_class_install_property (gobject_class, PROP_HUE,
+      g_param_spec_int ("hue", "Hue", "The hue of the video", -1000, 1000, 0,
+          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+  g_object_class_install_property (gobject_class, PROP_SATURATION,
+      g_param_spec_int ("saturation", "Saturation",
+          "The saturation of the video", -1000, 1000, 0,
+          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+  g_object_class_install_property (gobject_class, PROP_DISPLAY,
+      g_param_spec_string ("display", "Display", "X Display name", NULL,
+          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+  g_object_class_install_property (gobject_class, PROP_SYNCHRONOUS,
+      g_param_spec_boolean ("synchronous", "Synchronous",
+          "When enabled, runs "
+          "the X display in synchronous mode. (used only for debugging)", FALSE,
+          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+  g_object_class_install_property (gobject_class, PROP_PIXEL_ASPECT_RATIO,
+      g_param_spec_string ("pixel-aspect-ratio", "Pixel Aspect Ratio",
+          "The pixel aspect ratio of the device", "1/1",
+          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+  g_object_class_install_property (gobject_class, PROP_FORCE_ASPECT_RATIO,
+      g_param_spec_boolean ("force-aspect-ratio", "Force aspect ratio",
+          "When enabled, scaling will respect original aspect ratio", FALSE,
+          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+  g_object_class_install_property (gobject_class, PROP_DEVICE,
+      g_param_spec_string ("device", "Adaptor number",
+          "The number of the video adaptor", "0",
+          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+  g_object_class_install_property (gobject_class, PROP_DEVICE_NAME,
+      g_param_spec_string ("device-name", "Adaptor name",
+          "The name of the video adaptor", NULL,
+          G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
+
+  /**
+   * GstEvasPixmapSink:double-buffer
+   *
+   * Whether to double-buffer the output.
+   *
+   * Since: 0.10.14
+   */
+  g_object_class_install_property (gobject_class, PROP_DOUBLE_BUFFER,
+      g_param_spec_boolean ("double-buffer", "Double-buffer",
+          "Whether to double-buffer the output", TRUE,
+          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+  /**
+   * GstEvasPixmapSink:autopaint-colorkey
+   *
+   * Whether to autofill overlay with colorkey
+   *
+   * Since: 0.10.21
+   */
+  g_object_class_install_property (gobject_class, PROP_AUTOPAINT_COLORKEY,
+      g_param_spec_boolean ("autopaint-colorkey", "Autofill with colorkey",
+          "Whether to autofill overlay with colorkey", TRUE,
+          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+  /**
+   * GstEvasPixmapSink:colorkey
+   *
+   * Color to use for the overlay mask.
+   *
+   * Since: 0.10.21
+   */
+  g_object_class_install_property (gobject_class, PROP_COLORKEY,
+      g_param_spec_int ("colorkey", "Colorkey",
+          "Color to use for the overlay mask", G_MININT, G_MAXINT, 0,
+          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
+  /**
+   * GstEvasPixmapSink:pixmap-width
+   *
+   * Actual width of the pixmap.
+   */
+  g_object_class_install_property (gobject_class, PROP_PIXMAP_WIDTH,
+      g_param_spec_uint64 ("pixmap-width", "pixmap-width", "Width of the pixmap", 0, G_MAXUINT64, 0, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
+
+  /**
+   * GstEvasPixmapSink:pixmap-height
+   *
+   * Actual height of the pixmap.
+   */
+  g_object_class_install_property (gobject_class, PROP_PIXMAP_HEIGHT,
+      g_param_spec_uint64 ("pixmap-height", "pixmap-height", "Height of the pixmap", 0, G_MAXUINT64, 0, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
+
+#ifdef GST_EXT_XV_ENHANCEMENT
+  /**
+   * GstEvasPixmapSink:display-geometry-method
+   *
+   * Display geometrical method setting
+   */
+  g_object_class_install_property(gobject_class, PROP_DISPLAY_GEOMETRY_METHOD,
+    g_param_spec_enum("display-geometry-method", "Display geometry method",
+      "Geometrical method for display",
+      GST_TYPE_EVASPIXMAPSINK_DISPLAY_GEOMETRY_METHOD, DEF_DISPLAY_GEOMETRY_METHOD,
+      G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
+  /**
+   * GstEvasPixmapSink:dst-roi-x
+   *
+   * X value of Destination ROI
+   */
+  g_object_class_install_property (gobject_class, PROP_DST_ROI_X,
+      g_param_spec_int ("dst-roi-x", "Dst-ROI-X",
+          "X value of Destination ROI(only effective \"CUSTOM_ROI\")", 0, XV_SCREEN_SIZE_WIDTH, 0,
+          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
+  /**
+   * GstEvasPixmapSink:dst-roi-y
+   *
+   * Y value of Destination ROI
+   */
+  g_object_class_install_property (gobject_class, PROP_DST_ROI_Y,
+      g_param_spec_int ("dst-roi-y", "Dst-ROI-Y",
+          "Y value of Destination ROI(only effective \"CUSTOM_ROI\")", 0, XV_SCREEN_SIZE_HEIGHT, 0,
+          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
+  /**
+   * GstEvasPixmapSink:dst-roi-w
+   *
+   * W value of Destination ROI
+   */
+  g_object_class_install_property (gobject_class, PROP_DST_ROI_W,
+      g_param_spec_int ("dst-roi-w", "Dst-ROI-W",
+          "W value of Destination ROI(only effective \"CUSTOM_ROI\")", 0, XV_SCREEN_SIZE_WIDTH, 0,
+          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
+  /**
+   * GstEvasPixmapSink:dst-roi-h
+   *
+   * H value of Destination ROI
+   */
+  g_object_class_install_property (gobject_class, PROP_DST_ROI_H,
+      g_param_spec_int ("dst-roi-h", "Dst-ROI-H",
+          "H value of Destination ROI(only effective \"CUSTOM_ROI\")", 0, XV_SCREEN_SIZE_HEIGHT, 0,
+          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
+  /**
+   * GstEvasPixmapSink:stop-video
+   *
+   * Stop video for releasing video source buffer
+   */
+  g_object_class_install_property (gobject_class, PROP_STOP_VIDEO,
+      g_param_spec_int ("stop-video", "Stop-Video", "Stop video for releasing video source buffer", 0, 1, 0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+#endif
+
+  /**
+   * GstEvasPixmapSink:evas-object
+   *
+   * Evas image object for rendering
+   */
+  g_object_class_install_property (gobject_class, PROP_EVAS_OBJECT,
+       g_param_spec_pointer ("evas-object", "Destination Evas Object", "Destination evas image object", G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
+  /**
+   * GstEvasPixmapSink:visible
+   *
+   * visible setting for a evas image object
+   */
+  g_object_class_install_property (gobject_class, PROP_VISIBLE,
+       g_param_spec_boolean ("visible", "Visible", "When setting it false, evas image object does not show", TRUE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
+   /**
+   * GstEvasPixmapSink:origin-size
+   *
+   * Set pixmap size with media source's width and height
+   */
+  g_object_class_install_property (gobject_class, PROP_ORIGIN_SIZE,
+       g_param_spec_boolean ("origin-size", "Origin-Size", "When setting it true, pixmap will be created with media source's width and height", FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
+  gobject_class->finalize = gst_evaspixmapsink_finalize;
+
+  gstelement_class->change_state = GST_DEBUG_FUNCPTR (gst_evaspixmapsink_change_state);
+  gstbasesink_class->get_caps = GST_DEBUG_FUNCPTR (gst_evaspixmapsink_getcaps);
+  gstbasesink_class->set_caps = GST_DEBUG_FUNCPTR (gst_evaspixmapsink_setcaps);
+  gstbasesink_class->get_times = GST_DEBUG_FUNCPTR (gst_evaspixmapsink_get_times);
+  gstbasesink_class->event = GST_DEBUG_FUNCPTR (gst_evaspixmapsink_event);
+  videosink_class->show_frame = GST_DEBUG_FUNCPTR (gst_evaspixmapsink_show_frame);
+}
+
+/* Object typing & Creation */
+GType
+gst_evaspixmapsink_get_type (void)
+{
+  static GType evaspixmapsink_type = 0;
+
+  if (!evaspixmapsink_type) {
+    static const GTypeInfo evaspixmapsink_info = {
+      sizeof (GstEvasPixmapSinkClass),
+      gst_evaspixmapsink_base_init,
+      NULL,
+      (GClassInitFunc) gst_evaspixmapsink_class_init,
+      NULL,
+      NULL,
+      sizeof (GstEvasPixmapSink),
+      0,
+      (GInstanceInitFunc) gst_evaspixmapsink_init,
+    };
+    static const GInterfaceInfo iface_info = {
+      (GInterfaceInitFunc) gst_evaspixmapsink_interface_init,
+      NULL,
+      NULL,
+    };
+    static const GInterfaceInfo navigation_info = {
+      (GInterfaceInitFunc) gst_evaspixmapsink_navigation_init,
+      NULL,
+      NULL,
+    };
+    static const GInterfaceInfo colorbalance_info = {
+      (GInterfaceInitFunc) gst_evaspixmapsink_colorbalance_init,
+      NULL,
+      NULL,
+    };
+    static const GInterfaceInfo propertyprobe_info = {
+      (GInterfaceInitFunc) gst_evaspixmapsink_property_probe_interface_init,
+      NULL,
+      NULL,
+    };
+    evaspixmapsink_type = g_type_register_static (GST_TYPE_VIDEO_SINK, "GstEvasPixmapSink", &evaspixmapsink_info, 0);
+
+    g_type_add_interface_static (evaspixmapsink_type, GST_TYPE_IMPLEMENTS_INTERFACE, &iface_info);
+    g_type_add_interface_static (evaspixmapsink_type, GST_TYPE_NAVIGATION, &navigation_info);
+    g_type_add_interface_static (evaspixmapsink_type, GST_TYPE_COLOR_BALANCE, &colorbalance_info);
+    g_type_add_interface_static (evaspixmapsink_type, GST_TYPE_PROPERTY_PROBE, &propertyprobe_info);
+
+    /* register type and create class in a more safe place instead of at
+     * runtime since the type registration and class creation is not
+     * threadsafe. */
+    g_type_class_ref (gst_evaspixmap_buffer_get_type ());
+  }
+
+  return evaspixmapsink_type;
+}
+
+static gboolean
+plugin_init (GstPlugin *plugin)
+{
+       if (!gst_element_register (plugin, "evaspixmapsink", GST_RANK_NONE, GST_TYPE_EVASPIXMAPSINK)) {
+               return FALSE;
+       }
+       GST_DEBUG_CATEGORY_INIT (gst_debug_evaspixmapsink, "evaspixmapsink", 0, "evaspixmapsink element");
+       GST_DEBUG_CATEGORY_GET (GST_CAT_PERFORMANCE, "GST_PERFORMANCE");
+
+       return TRUE;
+}
+
+GST_PLUGIN_DEFINE (GST_VERSION_MAJOR, GST_VERSION_MINOR,
+       "evaspixmapsink","Evas image object render plugin using Xv extension", plugin_init,
+       VERSION, GST_LICENSE, GST_PACKAGE_NAME, GST_PACKAGE_ORIGIN)
diff --git a/evaspixmapsink/evaspixmapsink.h b/evaspixmapsink/evaspixmapsink.h
new file mode 100644 (file)
index 0000000..b61a6ac
--- /dev/null
@@ -0,0 +1,388 @@
+/*
+ * EvasPixmapSink
+ *
+ * Copyright (c) 2000 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Sangchul Lee <sc11.lee@samsung.com>
+ *
+ * This library is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the
+ * Free Software Foundation; either version 2.1 of the License, or (at your option)
+ * any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software Foundation, Inc., 51
+ * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#ifndef __GST_EVASPIXMAPSINK_H__
+#define __GST_EVASPIXMAPSINK_H__
+
+#include <gst/video/gstvideosink.h>
+#include <mm_ta.h>
+
+#ifdef HAVE_XSHM
+#include <sys/types.h>
+#include <sys/ipc.h>
+#include <sys/shm.h>
+#endif /* HAVE_XSHM */
+
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+
+#ifdef HAVE_XSHM
+#include <X11/extensions/XShm.h>
+#endif /* HAVE_XSHM */
+
+#include <X11/extensions/Xv.h>
+#include <X11/extensions/Xvlib.h>
+#include <X11/extensions/Xdamage.h>
+#include <X11/extensions/damagewire.h>
+#ifdef GST_EXT_XV_ENHANCEMENT
+#include <X11/Xatom.h>
+#include <stdio.h>
+#endif
+
+#include <Evas.h>
+#include <Ecore.h>
+#include <Ecore_X.h>
+
+#include <string.h>
+#include <math.h>
+#include <stdlib.h>
+
+#define MAX_PLANE_NUM          3
+#define MAX_BUFFER_NUM         20
+#define MAX_GEM_BUFFER_NUM     (MAX_PLANE_NUM * MAX_BUFFER_NUM)
+typedef struct _gem_info_t {
+       int dmabuf_fd;
+       unsigned int gem_handle;
+       unsigned int gem_name;
+} gem_info_t;
+
+
+G_BEGIN_DECLS
+
+#define GST_TYPE_EVASPIXMAPSINK \
+  (gst_evaspixmapsink_get_type())
+#define GST_EVASPIXMAPSINK(obj) \
+  (G_TYPE_CHECK_INSTANCE_CAST((obj), GST_TYPE_EVASPIXMAPSINK, GstEvasPixmapSink))
+#define GST_EVASPIXMAPSINK_CLASS(klass) \
+  (G_TYPE_CHECK_CLASS_CAST((klass), GST_TYPE_EVASPIXMAPSINK, GstEvasPixmapSinkClass))
+#define GST_IS_EVASPIXMAPSINK(obj) \
+  (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_TYPE_EVASPIXMAPSINK))
+#define GST_IS_EVASPIXMAPSINK_CLASS(klass) \
+  (G_TYPE_CHECK_CLASS_TYPE((klass), GST_TYPE_EVASPIXMAPSINK))
+
+#ifdef GST_EXT_XV_ENHANCEMENT
+#define XV_SCREEN_SIZE_WIDTH 4096
+#define XV_SCREEN_SIZE_HEIGHT 4096
+#endif /* GST_EXT_XV_ENHANCEMENT */
+#define MARGIN_OF_ERROR 0.005
+
+typedef struct _GstXContext GstXContext;
+typedef struct _GstXPixmap GstXPixmap;
+typedef struct _GstEvasPixmapFormat GstEvasPixmapFormat;
+typedef struct _GstEvasPixmapBuffer GstEvasPixmapBuffer;
+typedef struct _GstEvasPixmapBufferClass GstEvasPixmapBufferClass;
+typedef struct _GstEvasPixmapSink GstEvasPixmapSink;
+typedef struct _GstEvasPixmapSinkClass GstEvasPixmapSinkClass;
+
+/*
+ * GstXContext:
+ * @disp: the X11 Display of this context
+ * @screen: the default Screen of Display @disp
+ * @screen_num: the Screen number of @screen
+ * @visual: the default Visual of Screen @screen
+ * @root: the root Window of Display @disp
+ * @white: the value of a white pixel on Screen @screen
+ * @black: the value of a black pixel on Screen @screen
+ * @depth: the color depth of Display @disp
+ * @bpp: the number of bits per pixel on Display @disp
+ * @endianness: the endianness of image bytes on Display @disp
+ * @width: the width in pixels of Display @disp
+ * @height: the height in pixels of Display @disp
+ * @widthmm: the width in millimeters of Display @disp
+ * @heightmm: the height in millimeters of Display @disp
+ * @par: the pixel aspect ratio calculated from @width, @widthmm and @height,
+ * @heightmm ratio
+ * @use_xshm: used to known wether of not XShm extension is usable or not even
+ * if the Extension is present
+ * @xv_port_id: the XVideo port ID
+ * @im_format: used to store at least a valid format for XShm calls checks
+ * @formats_list: list of supported image formats on @xv_port_id
+ * @channels_list: list of #GstColorBalanceChannels
+ * @caps: the #GstCaps that Display @disp can accept
+ *
+ * Structure used to store various informations collected/calculated for a
+ * Display.
+ */
+struct _GstXContext {
+       Display *disp;
+
+       Screen *screen;
+       gint screen_num;
+
+       Visual *visual;
+
+       Window root;
+
+       gulong white, black;
+
+       gint depth;
+       gint bpp;
+       gint endianness;
+
+       gint width, height;
+       gint widthmm, heightmm;
+       GValue *par;                  /* calculated pixel aspect ratio */
+
+       gboolean use_xshm;
+
+       XvPortID xv_port_id;
+       guint nb_adaptors;
+       gchar ** adaptors;
+       gint im_format;
+
+       GList *formats_list;
+       GList *channels_list;
+
+       GstCaps *caps;
+};
+
+/*
+ * GstXPixmap:
+ * @pixmap: the pixmap ID of this X11 pixmap
+ * @width: the width in pixels of Pixmap @pixmap
+ * @height: the height in pixels of Pixmap @pixmap
+ * @gc: the Graphical Context of Pixmap @pixmap
+ *
+ * Structure used to store informations about a Pixmap.
+ */
+struct _GstXPixmap {
+       Pixmap pixmap;
+#ifdef GST_EXT_XV_ENHANCEMENT
+       gint x, y;
+#endif
+       gint width, height;
+       GC gc;
+};
+
+/**
+ * GstEvasPixmapFormat:
+ * @format: the image format
+ * @caps: generated #GstCaps for this image format
+ *
+ * Structure storing image format to #GstCaps association.
+ */
+struct _GstEvasPixmapFormat {
+       gint format;
+       GstCaps *caps;
+};
+
+/**
+ * GstEvasPixmapBuffer:
+ * @evaspixmapsink: a reference to our #GstEvasPixmapSink
+ * @xvimage: the XvImage of this buffer
+ * @width: the width in pixels of XvImage @xvimage
+ * @height: the height in pixels of XvImage @xvimage
+ * @im_format: the image format of XvImage @xvimage
+ * @size: the size in bytes of XvImage @xvimage
+ *
+ * Subclass of #GstBuffer containing additional information about an XvImage.
+ */
+struct _GstEvasPixmapBuffer {
+       GstBuffer buffer;
+
+       /* Reference to the evaspixmapsink we belong to */
+       GstEvasPixmapSink *evaspixmapsink;
+       XvImage *xvimage;
+
+#ifdef HAVE_XSHM
+       XShmSegmentInfo SHMInfo;
+#endif /* HAVE_XSHM */
+
+       gint width, height;
+       gint im_format;
+       size_t size;
+};
+
+/**
+ * GstEvasPixmapSink:
+ * @display_name: the name of the Display we want to render to
+ * @xcontext: our instance's #GstXContext
+ * @xpixmap: the #GstXPixmap we are rendering to
+ * @fps_n: the framerate fraction numerator
+ * @fps_d: the framerate fraction denominator
+ * @x_lock: used to protect X calls as we are not using the XLib in threaded
+ * mode
+ * @flow_lock: used to protect data flow routines from external calls such as
+ * methods from the #GstXOverlay interface
+ * @par: used to override calculated pixel aspect ratio from @xcontext
+ * @synchronous: used to store if XSynchronous should be used or not (for
+ * debugging purpose only)
+ * @keep_aspect: used to remember if reverse negotiation scaling should respect
+ * aspect ratio
+ * @brightness: used to store the user settings for color balance brightness
+ * @contrast: used to store the user settings for color balance contrast
+ * @hue: used to store the user settings for color balance hue
+ * @saturation: used to store the user settings for color balance saturation
+ * @cb_changed: used to store if the color balance settings where changed
+ * @video_width: the width of incoming video frames in pixels
+ * @video_height: the height of incoming video frames in pixels
+ *
+ * The #GstEvasPixmapSink data structure.
+ */
+struct _GstEvasPixmapSink {
+       /* Our element stuff */
+       GstVideoSink videosink;
+
+       char *display_name;
+       guint adaptor_no;
+
+       GstXContext *xcontext;
+       GstXPixmap *xpixmap;
+       GstEvasPixmapBuffer *evas_pixmap_buf;
+
+       GThread *event_thread;
+       gboolean running;
+
+       gint fps_n;
+       gint fps_d;
+
+       GMutex *x_lock;
+       GMutex *flow_lock;
+
+       /* object-set pixel aspect ratio */
+       GValue *par;
+
+       gboolean synchronous;
+       gboolean double_buffer;
+       gboolean keep_aspect;
+
+       gint brightness;
+       gint contrast;
+       gint hue;
+       gint saturation;
+       gboolean cb_changed;
+
+       /* size of incoming video, used as the size for XvImage */
+       guint video_width, video_height;
+
+       /* display sizes, used for clipping the image */
+       gint disp_x, disp_y;
+       gint disp_width, disp_height;
+
+       /* port attributes */
+       gboolean autopaint_colorkey;
+       gint colorkey;
+
+       /* port features */
+       gboolean have_autopaint_colorkey;
+       gboolean have_colorkey;
+       gboolean have_double_buffer;
+
+       /* target video rectagle */
+       GstVideoRectangle render_rect;
+       gboolean have_render_rect;
+
+#ifdef GST_EXT_XV_ENHANCEMENT
+       /* display */
+       guint display_geometry_method;
+       GstVideoRectangle dst_roi;
+       guint scr_w, scr_h;
+       /* needed if fourcc is one if S series */
+       guint aligned_width;
+       guint aligned_height;
+#endif
+       gboolean stop_video;
+
+       /* evas object */
+       Evas_Object *eo;
+       Evas_Coord w;
+       Evas_Coord h;
+       gboolean visible;
+
+       /* pixmap */
+       gboolean do_link;
+       gboolean use_origin_size;
+       gboolean former_origin_size;
+
+       /* damage event */
+       Damage damage;
+       int damage_case;
+       Ecore_Event_Handler *handler;
+       Ecore_Pipe *epipe;
+
+       gint drm_fd;
+       gem_info_t gem_info[MAX_GEM_BUFFER_NUM];
+};
+
+#ifdef GST_EXT_XV_ENHANCEMENT
+/* max plane count *********************************************************/
+#define MPLANE_IMGB_MAX_COUNT         (4)
+
+/* image buffer definition ***************************************************
+
+    +------------------------------------------+ ---
+    |                                          |  ^
+    |     uaddr[], index[]                     |  |
+    |     +---------------------------+ ---    |  |
+    |     |                           |  ^     |  |
+    |     |<-------- width[] -------->|  |     |  |
+    |     |                           |  |     |  |
+    |     |                           |        |
+    |     |                           |height[]|elevation[]
+    |     |                           |        |
+    |     |                           |  |     |  |
+    |     |                           |  |     |  |
+    |     |                           |  v     |  |
+    |     +---------------------------+ ---    |  |
+    |                                          |  v
+    +------------------------------------------+ ---
+
+    |<----------------- stride[] ------------------>|
+*/
+typedef struct _GstMultiPlaneImageBuffer GstMultiPlaneImageBuffer;
+struct _GstMultiPlaneImageBuffer
+{
+    GstBuffer buffer;
+
+    /* width of each image plane */
+    gint      width[MPLANE_IMGB_MAX_COUNT];
+    /* height of each image plane */
+    gint      height[MPLANE_IMGB_MAX_COUNT];
+    /* stride of each image plane */
+    gint      stride[MPLANE_IMGB_MAX_COUNT];
+    /* elevation of each image plane */
+    gint      elevation[MPLANE_IMGB_MAX_COUNT];
+    /* user space address of each image plane */
+    gpointer uaddr[MPLANE_IMGB_MAX_COUNT];
+    /* Index of real address of each image plane, if needs */
+    gpointer index[MPLANE_IMGB_MAX_COUNT];
+    /* left postion, if needs */
+    gint      x;
+    /* top position, if needs */
+    gint      y;
+    /* to align memory */
+    gint      __dummy2;
+    /* arbitrary data */
+    gint      data[16];
+};
+#endif /* GST_EXT_XV_ENHANCEMENT */
+
+struct _GstEvasPixmapSinkClass {
+  GstVideoSinkClass parent_class;
+};
+
+GType gst_evaspixmapsink_get_type(void);
+
+G_END_DECLS
+
+#endif /* __GST_EVASPIXMAPSINK_H__ */
diff --git a/evaspixmapsink/xv_types.h b/evaspixmapsink/xv_types.h
new file mode 100644 (file)
index 0000000..9ed7939
--- /dev/null
@@ -0,0 +1,41 @@
+/*                                                              */
+/* File name : xv_types.h                                       */
+/* Author : YoungHoon Jung (yhoon.jung@samsung.com)             */
+/* Protocol Version : 1.0.1 (Dec 16th 2009)                       */
+/* This file is for describing Xv APIs' buffer encoding method. */
+/*                                                              */
+
+#define XV_PUTIMAGE_HEADER     0xDEADCD01
+#define XV_PUTIMAGE_VERSION    0x00010001
+
+/* Return Values */
+#define XV_OK 0
+#define XV_HEADER_ERROR -1
+#define XV_VERSION_MISMATCH -2
+
+/* Video Mode */
+#define VIDEO_MODE_TV_LCD      1
+#define VIDEO_MODE_TVONLY      2
+#define VIDEO_MODE_LCDONLY     3
+#define VIDEO_MODE_TVCAPTION   4
+
+/* Buffer Type */
+#define XV_BUF_TYPE_DMABUF  0
+#define XV_BUF_TYPE_LEGACY  1
+
+/* Data structure for XvPutImage / XvShmPutImage */
+typedef struct {
+       unsigned int _header; /* for internal use only */
+       unsigned int _version; /* for internal use only */
+
+       unsigned int YBuf;
+       unsigned int CbBuf;
+       unsigned int CrBuf;
+       unsigned int BufType;
+} XV_PUTIMAGE_DATA, * XV_PUTIMAGE_DATA_PTR;
+
+static void XV_PUTIMAGE_INIT_DATA(XV_PUTIMAGE_DATA_PTR data)
+{
+       data->_header = XV_PUTIMAGE_HEADER;
+       data->_version = XV_PUTIMAGE_VERSION;
+}
index 8d03eec..f6042db 100644 (file)
@@ -1,7 +1,7 @@
 Name:       gst-plugins-ext0.10
-Version:    0.2.20
+Version:    0.3.0
 Summary:    GStreamer extra plugins (common)
-Release:    0
+Release:    1
 Group:      libs
 License:    LGPLv2+
 Source0:    %{name}-%{version}.tar.gz
@@ -20,8 +20,10 @@ BuildRequires:       pkgconfig(xext)
 BuildRequires: pkgconfig(xv)
 BuildRequires: pkgconfig(xdamage)
 BuildRequires: pkgconfig(libdrm)
-BuildRequires:  pkgconfig(libdrm_slp)
+BuildRequires:  pkgconfig(libtbm)
 BuildRequires: libdrm-devel
+BuildRequires: pkgconfig(dri2proto)
+BuildRequires: pkgconfig(xfixes)
 
 %description
 GStreamer extra plugins (common)
@@ -31,7 +33,7 @@ GStreamer extra plugins (common)
 
 
 %build
-export CFLAGS+=" -DGST_EXT_TIME_ANALYSIS -DEXPORT_API=\"__attribute__((visibility(\\\"default\\\")))\" "
+export CFLAGS+=" -DGST_EXT_TIME_ANALYSIS -DGST_EXT_XV_ENHANCEMENT -DEXPORT_API=\"__attribute__((visibility(\\\"default\\\")))\" "
 
 ./autogen.sh --disable-static
 %configure --disable-static
index a448b0e..d37cedb 100644 (file)
@@ -18,8 +18,8 @@ libgstxvimagesrc_la_SOURCES = gstxvimagesrc.c
 
 # flags used to compile this plugin
 # add other _CFLAGS and _LIBS as needed
-libgstxvimagesrc_la_CFLAGS = $(GST_CFLAGS)  $(GST_PLUGINS_BASE_CFLAGS) $(GST_BASE_CFLAGS) $(DRM_SLP_CFLAGS) $(DRI2_CFLAGS) $(X11_CFLAGS) $(XEXT_CFLAGS) $(XV_CFLAGS) $(XDAMAGE_CFLAGS) $(DRM_DEVEL_CFLAGS) $(DRM_CFLAGS)
-libgstxvimagesrc_la_LIBADD = $(GST_LIBS) $(GST_PLUGINS_BASE_LIBS) $(GST_BASE_LIBS) $(DRM_SLP_LIBS)$(DRI2_LIBS) $(X11_LIBS) $(XEXT_LIBS) $(XV_LIBS) $(XDAMAGE_LIBS) $(DRM_LIBS) $(DRM_DEVEL_LIBS)
+libgstxvimagesrc_la_CFLAGS = $(GST_CFLAGS)  $(GST_PLUGINS_BASE_CFLAGS) $(GST_BASE_CFLAGS) $(TBM_CFLAGS) $(DRI2_CFLAGS) $(X11_CFLAGS) $(XEXT_CFLAGS) $(XV_CFLAGS) $(XDAMAGE_CFLAGS) $(DRM_DEVEL_CFLAGS) $(DRM_CFLAGS)
+libgstxvimagesrc_la_LIBADD = $(GST_LIBS) $(GST_PLUGINS_BASE_LIBS) $(GST_BASE_LIBS) $(TBM_LIBS)$(DRI2_LIBS) $(X11_LIBS) $(XEXT_LIBS) $(XV_LIBS) $(XDAMAGE_LIBS) $(DRM_LIBS) $(DRM_DEVEL_LIBS)
 libgstxvimagesrc_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
 
 # headers we need but don't want installed
old mode 100755 (executable)
new mode 100644 (file)
index 066d1ff..0964ad2
@@ -203,9 +203,9 @@ static gboolean gst_xv_image_src_unlock (GstBaseSrc * bsrc);
 static gboolean gst_xv_image_src_unlock_stop (GstBaseSrc * bsrc);
 static gboolean gst_xv_image_src_setcaps (GstBaseSrc * bsrc, GstCaps * caps);
 
-static drm_slp_bufmgr bufmgr_get (Display *dpy, Pixmap pixmap);
+static tbm_bufmgr bufmgr_get (Display *dpy, Pixmap pixmap);
 static int port_get (Display *dpy, unsigned int id);
-static void pixmap_update (GstXVImageSrc * src,Display *dpy, drm_slp_bufmgr bufmgr, Pixmap pixmap,
+static void pixmap_update (GstXVImageSrc * src,Display *dpy, tbm_bufmgr bufmgr, Pixmap pixmap,
                int x, int y, int width, int height);
 static Pixmap pixmap_create (GstXVImageSrc * src, Display *dpy, int width, int height);
 
@@ -922,9 +922,9 @@ static void* gst_xv_image_src_update_thread (void * asrc)
       gst_buffer_unref(outbuf);
     }
     update_done:
-      if (src->virtual) drm_slp_bo_unmap(src->bo, DRM_SLP_DEVICE_CPU);
+      if (src->virtual) tbm_bo_unmap(src->bo);
       src->virtual = NULL;
-      if (src->bo) drm_slp_bo_unref(src->bo);
+      if (src->bo) tbm_bo_unref(src->bo);
       src->bo = NULL;
       if (src->dri2_buffers) free(src->dri2_buffers);
       src->dri2_buffers = NULL;
@@ -959,7 +959,7 @@ static void* gst_xv_image_src_update_thread (void * asrc)
     src->atom_stream_off = 0;
   }
   if (src->bufmgr) {
-    drm_slp_bufmgr_destroy (src->bufmgr);
+    tbm_bufmgr_deinit (src->bufmgr);
     src->bufmgr = NULL;
   }
   if (src->p > 0) {
@@ -986,7 +986,7 @@ finish:
     XvSetPortAttribute (src->dpy, src->p, src->atom_stream_off, 1);
     src->atom_stream_off = 0;
   }
-  if (src->bufmgr) drm_slp_bufmgr_destroy (src->bufmgr);
+  if (src->bufmgr) tbm_bufmgr_deinit (src->bufmgr);
   src->bufmgr = NULL;
   if (src->p > 0) XvUngrabPort (src->dpy, src->p, 0);
   src->p = 0;
@@ -1000,11 +1000,11 @@ finish:
   return NULL;
 }
 
-static drm_slp_bufmgr bufmgr_get (Display *dpy, Pixmap pixmap)
+static tbm_bufmgr bufmgr_get (Display *dpy, Pixmap pixmap)
 {
   int screen;
   int drm_fd;
-  drm_slp_bufmgr bufmgr;
+  tbm_bufmgr bufmgr;
   int eventBase, errorBase;
   int dri2Major, dri2Minor;
   char *driverName, *deviceName;
@@ -1045,7 +1045,7 @@ static drm_slp_bufmgr bufmgr_get (Display *dpy, Pixmap pixmap)
     return NULL;
   }
   // drm slp buffer manager init
-  bufmgr = drm_slp_bufmgr_init (drm_fd, NULL);
+  bufmgr = tbm_bufmgr_init (drm_fd);
   if (!bufmgr) {
     GST_ERROR ("!!Error : fail to init buffer manager ");
     close (drm_fd);
@@ -1112,13 +1112,14 @@ static int port_get (Display *dpy, unsigned int id)
   return -1;
 }
 
-static void pixmap_update (GstXVImageSrc * src, Display *dpy, drm_slp_bufmgr bufmgr, Pixmap pixmap,
+static void pixmap_update (GstXVImageSrc * src, Display *dpy, tbm_bufmgr bufmgr, Pixmap pixmap,
                int x, int y, int width, int height)
 {
   unsigned int attachments[1];
   int dri2_count, dri2_out_count;
   int dri2_width, dri2_height, dri2_stride;
   int opt;
+  tbm_bo_handle temp_virtual;
   attachments[0] = DRI2BufferFrontLeft;
   dri2_count = 1;
   src->dri2_buffers = DRI2GetBuffers (dpy, pixmap, &dri2_width, &dri2_height, attachments, dri2_count, &dri2_out_count);
@@ -1130,23 +1131,24 @@ static void pixmap_update (GstXVImageSrc * src, Display *dpy, drm_slp_bufmgr buf
     GST_ERROR ("[Error] : a handle of the dri2 buffer is null  ");
     goto update_done;
   }
-  src->bo = drm_slp_bo_import(bufmgr, src->dri2_buffers[0].name);
+  src->bo = tbm_bo_import(bufmgr, src->dri2_buffers[0].name);
   if (!src->bo) {
     GST_ERROR ("[Error] : cannot import bo (key:%d)", src->dri2_buffers[0].name);
     goto update_done;
   }
   dri2_stride = src->dri2_buffers[0].pitch;
-  opt = DRM_SLP_OPTION_READ|DRM_SLP_OPTION_WRITE;
-  src->virtual = drm_slp_bo_map (src->bo, DRM_SLP_DEVICE_CPU, opt);
+  opt = TBM_OPTION_READ|TBM_OPTION_WRITE;
+  temp_virtual = tbm_bo_map (src->bo, TBM_DEVICE_CPU, opt);
+  src->virtual = temp_virtual.ptr;
   if (!src->virtual) {
     GST_ERROR ("[Error] : fail to map ");
     goto update_done;
   }
   return;
 update_done:
-  if (src->virtual) drm_slp_bo_unmap(src->bo, DRM_SLP_DEVICE_CPU);
+  if (src->virtual) tbm_bo_unmap(src->bo);
   src->virtual = NULL;
-  if (src->bo) drm_slp_bo_unref(src->bo);
+  if (src->bo) tbm_bo_unref(src->bo);
   src->bo = NULL;
   if (src->dri2_buffers) free(src->dri2_buffers);
   src->dri2_buffers = NULL;
old mode 100755 (executable)
new mode 100644 (file)
index 4765e32..0448360
@@ -46,7 +46,7 @@
 #include <X11/extensions/Xdamage.h>
 
 #include <dri2.h> //libdri2-dev, libdrm-dev
-#include <drm_slp_bufmgr.h>
+#include <tbm_bufmgr.h>
 
 #include "xv_types.h"
 
@@ -87,9 +87,9 @@ struct _GstXVImageSrc {
   guint32 format_id;
   Damage damage;
   int damage_base;
-  drm_slp_bufmgr bufmgr;
+  tbm_bufmgr bufmgr;
   void *virtual;
-  drm_slp_bo bo;
+  tbm_bo bo;
   DRI2Buffer* dri2_buffers;
   guint64 running_time;
   guint64 base_time;