Added Samsung specific code.
authorAndrey Shelest <a.shelest@samsung.com>
Mon, 23 Jun 2014 11:39:03 +0000 (14:39 +0300)
committerPhilippe Coval <philippe.coval@open.eurogiciel.org>
Tue, 18 Nov 2014 17:26:07 +0000 (18:26 +0100)
-Support of Samsung extention video formats ITLV, SN12, ST12.
-Support video texture overlay of OSP layer.
-Interface for camera control.

Change-Id: Ice02ca01e1b555036c1a80ea1bdea0f0df9bb218

24 files changed:
configure.ac
gst-libs/gst/riff/riff-ids.h
gst-libs/gst/riff/riff-media.c
gst-libs/gst/video/Makefile.am
gst-libs/gst/video/cameracontrol.c [new file with mode: 0644]
gst-libs/gst/video/cameracontrol.h [new file with mode: 0644]
gst-libs/gst/video/cameracontrolchannel.c [new file with mode: 0644]
gst-libs/gst/video/cameracontrolchannel.h [new file with mode: 0644]
gst-libs/gst/video/video-format.c
gst-libs/gst/video/video-format.h
gst-libs/gst/video/video-info.c
gst/playback/gstplaysink.c
gst/typefind/gsttypefindfunctions.c
gst/videoconvert/gstvideoconvert.c
packaging/gst-plugins-base.changes
packaging/gst-plugins-base.spec
sys/xvimage/Makefile.am
sys/xvimage/xv_types.h [new file with mode: 0644]
sys/xvimage/xvcontext.c
sys/xvimage/xvcontext.h
sys/xvimage/xvimageallocator.c
sys/xvimage/xvimageallocator.h
sys/xvimage/xvimagesink.c
sys/xvimage/xvimagesink.h

index 25b64cc..a441c51 100644 (file)
@@ -820,6 +820,30 @@ dnl whatevertarget_LIBS and -L flags here affect the rest of the linking
 GST_PLUGIN_LDFLAGS="-module -avoid-version -export-symbols-regex '^[_]*gst_plugin_.*' $GST_ALL_LDFLAGS"
 AC_SUBST(GST_PLUGIN_LDFLAGS)
 
+dnl use xfixes
+PKG_CHECK_MODULES(XFIXES, xfixes)
+AC_SUBST(XFIXES_CFLAGS)
+AC_SUBST(XFIXES_LIBS)
+
+dnl use dri2proto
+PKG_CHECK_MODULES(DRI2PROTO, dri2proto)
+AC_SUBST(DRI2PROTO_CFLAGS)
+AC_SUBST(DRI2PROTO_LIBS)
+
+dnl use dri2
+PKG_CHECK_MODULES(DRI2, libdri2)
+AC_SUBST(DRI2_CFLAGS)
+AC_SUBST(DRI2_LIBS)
+
+dnl use tbm
+PKG_CHECK_MODULES(TBM, libtbm)
+AC_SUBST(TBM_CFLAGS)
+AC_SUBST(TBM_LIBS)
+
+PKG_CHECK_MODULES(MMTA, mm-ta)
+AC_SUBST(MMTA_CFLAGS)
+AC_SUBST(MMTA_LIBS)
+
 dnl *** output files ***
 
 $MKDIR_P tests/check/orc
index acc75d5..8518951 100644 (file)
@@ -439,6 +439,7 @@ typedef struct _gst_riff_strf_auds {       /* == WaveHeader (?) */
 #define GST_RIFF_WAVE_FORMAT_LH_CODEC       (0x1100)
 #define GST_RIFF_WAVE_FORMAT_NORRIS         (0x1400)
 #define GST_RIFF_WAVE_FORMAT_SOUNDSPACE_MUSICOMPRESS (0x1500)
+#define GST_RIFF_WAVE_FORMAT_AAC_PR         (0x1601)  /* Microsoft Playready */
 #define GST_RIFF_WAVE_FORMAT_A52            (0x2000)
 #define GST_RIFF_WAVE_FORMAT_DTS            (0x2001)
 #define GST_RIFF_WAVE_FORMAT_SONIC          (0x2048)
index e4d877e..6d12b4c 100644 (file)
@@ -1503,6 +1503,7 @@ gst_riff_create_audio_caps (guint16 codec_id,
     case GST_RIFF_WAVE_FORMAT_AAC:
     case GST_RIFF_WAVE_FORMAT_AAC_AC:
     case GST_RIFF_WAVE_FORMAT_AAC_pm:
+    case GST_RIFF_WAVE_FORMAT_AAC_PR:
     {
       channels_max = 8;
       caps = gst_caps_new_simple ("audio/mpeg",
index 3932947..3af1263 100644 (file)
@@ -17,6 +17,8 @@ lib_LTLIBRARIES = libgstvideo-@GST_API_VERSION@.la
 CLEANFILES = $(BUILT_SOURCES)
 
 libgstvideo_@GST_API_VERSION@_la_SOURCES = \
+       cameracontrol.c         \
+       cameracontrolchannel.c  \
        colorbalance.c          \
        colorbalancechannel.c   \
        navigation.c            \
@@ -45,6 +47,8 @@ nodist_libgstvideo_@GST_API_VERSION@_la_SOURCES = $(BUILT_SOURCES)
 
 libgstvideo_@GST_API_VERSION@includedir = $(includedir)/gstreamer-@GST_API_VERSION@/gst/video
 libgstvideo_@GST_API_VERSION@include_HEADERS = \
+       cameracontrol.h         \
+       cameracontrolchannel.h  \
        colorbalance.h          \
        colorbalancechannel.h   \
        navigation.h            \
diff --git a/gst-libs/gst/video/cameracontrol.c b/gst-libs/gst/video/cameracontrol.c
new file mode 100644 (file)
index 0000000..80da4d3
--- /dev/null
@@ -0,0 +1,523 @@
+/*
+ * GStreamer Camera Control Interface
+ *
+ * Copyright (c) 2000 - 2012 Samsung Electronics Co., Ltd.
+ *
+ * Contact: Jeongmo Yang <jm80.yang@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
+ *
+ */
+
+/*============================================================================================
+EDIT HISTORY FOR MODULE
+
+This section contains comments describing changes made to the module.
+Notice that changes are listed in reverse chronological order.
+
+when            who                             what, where, why
+---------       ------------------------        ----------------------------------------------
+12/09/08        jm80.yang@samsung.com           Created
+
+============================================================================================*/
+
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "cameracontrol.h"
+//#include "interfaces-marshal.h"
+
+/**
+ * SECTION:gstcameracontrol
+ * @short_description: Interface for camera control
+ */
+
+enum {
+       CONTROL_VALUE_CHANGED,
+       CONTROL_LAST_SIGNAL
+};
+
+static void gst_camera_control_class_init(GstCameraControlClass *klass);
+
+static guint gst_camera_control_signals[CONTROL_LAST_SIGNAL] = { 0 };
+
+GType gst_camera_control_get_type(void)
+{
+       static GType gst_camera_control_type = 0;
+
+       if (!gst_camera_control_type) {
+               static const GTypeInfo gst_camera_control_info =
+               {
+                       sizeof(GstCameraControlClass),
+                       (GBaseInitFunc)gst_camera_control_class_init,
+                       NULL,
+                       NULL,
+                       NULL,
+                       NULL,
+                       0,
+                       0,
+                       NULL,
+               };
+
+               gst_camera_control_type = g_type_register_static(G_TYPE_INTERFACE,
+                                                                "GstCameraControl",
+                                                                &gst_camera_control_info,
+                                                                0);
+               //g_type_interface_add_prerequisite(gst_camera_control_type, GST_TYPE_IMPLEMENTS_INTERFACE);
+       }
+
+       return gst_camera_control_type;
+}
+
+static void gst_camera_control_class_init(GstCameraControlClass *klass)
+{
+       static gboolean initialized = FALSE;
+
+       if (!initialized) {
+               gst_camera_control_signals[CONTROL_VALUE_CHANGED] =
+                       g_signal_new("control-value-changed",
+                                    GST_TYPE_CAMERA_CONTROL, G_SIGNAL_RUN_LAST,
+                                    G_STRUCT_OFFSET(GstCameraControlClass, value_changed),
+                                    NULL, NULL, NULL,
+                                    //gst_interfaces_marshal_VOID__OBJECT_INT,
+                                    G_TYPE_NONE, 2, GST_TYPE_CAMERA_CONTROL_CHANNEL, G_TYPE_INT);
+
+               initialized = TRUE;
+       }
+
+       // TODO :
+       klass->camera_control_type = 0;
+
+       /* defauld virtual functions */
+       klass->list_channels = NULL;
+       klass->set_exposure = NULL;
+       klass->get_exposure = NULL;
+       klass->set_capture_mode = NULL;
+       klass->get_capture_mode = NULL;
+       klass->set_strobe = NULL;
+       klass->get_strobe = NULL;
+       klass->set_detect = NULL;
+       klass->get_detect = NULL;
+       klass->set_value = NULL;
+       klass->get_value = NULL;
+       klass->set_zoom  = NULL;
+       klass->get_zoom  = NULL;
+       klass->set_focus = NULL;
+       klass->get_focus = NULL;
+       klass->start_auto_focus = NULL;
+       klass->stop_auto_focus = NULL;
+       klass->set_focus_level = NULL;
+       klass->get_focus_level = NULL;
+       klass->set_auto_focus_area = NULL;
+       klass->get_auto_focus_area = NULL;
+       klass->set_wdr = NULL;
+       klass->get_wdr = NULL;
+       klass->set_ahs = NULL;
+       klass->get_ahs = NULL;
+       klass->set_part_color = NULL;
+       klass->get_part_color = NULL;
+       klass->get_exif_info = NULL;
+       klass->set_capture_command = NULL;
+       klass->start_face_zoom = NULL;
+       klass->stop_face_zoom = NULL;
+}
+
+const GList* gst_camera_control_list_channels(GstCameraControl *control)
+{
+       GstCameraControlClass *klass = GST_CAMERA_CONTROL_GET_CLASS(control);
+
+       if (klass->list_channels) {
+               return klass->list_channels(control);
+       }
+
+       return NULL;
+}
+
+
+gboolean gst_camera_control_set_value(GstCameraControl *control, GstCameraControlChannel *control_channel)
+{
+       GstCameraControlClass *klass = GST_CAMERA_CONTROL_GET_CLASS(control);
+
+       if (klass->set_value) {
+               return klass->set_value(control, control_channel);
+       }
+
+       return FALSE;
+}
+
+gboolean gst_camera_control_get_value(GstCameraControl *control, GstCameraControlChannel *control_channel)
+{
+       GstCameraControlClass *klass = GST_CAMERA_CONTROL_GET_CLASS(control);
+
+       if (klass->get_value) {
+               return klass->get_value(control, control_channel);
+       }
+
+       return FALSE;
+}
+
+
+
+gboolean gst_camera_control_set_exposure(GstCameraControl *control, gint type, gint value1, gint value2)
+{
+       GstCameraControlClass *klass = GST_CAMERA_CONTROL_GET_CLASS(control);
+
+       if (klass->set_exposure) {
+               return klass->set_exposure(control, type, value1, value2);
+       }
+
+       return FALSE;
+}
+
+gboolean gst_camera_control_get_exposure(GstCameraControl *control, gint type, gint *value1, gint *value2)
+{
+       GstCameraControlClass *klass = GST_CAMERA_CONTROL_GET_CLASS(control);
+
+       if (klass->get_exposure) {
+               return klass->get_exposure(control, type, value1, value2);
+       }
+
+       return FALSE;
+}
+
+gboolean gst_camera_control_set_capture_mode(GstCameraControl *control, gint type, gint value)
+{
+       GstCameraControlClass *klass = GST_CAMERA_CONTROL_GET_CLASS(control);
+
+       if (klass->set_capture_mode) {
+               return klass->set_capture_mode(control, type, value);
+       }
+
+       return FALSE;
+}
+
+gboolean gst_camera_control_get_capture_mode(GstCameraControl *control, gint type, gint *value)
+{
+       GstCameraControlClass *klass = GST_CAMERA_CONTROL_GET_CLASS(control);
+
+       if (klass->get_capture_mode) {
+               return klass->get_capture_mode(control, type, value);
+       }
+
+       return FALSE;
+}
+
+gboolean gst_camera_control_set_strobe(GstCameraControl *control, gint type, gint value)
+{
+       GstCameraControlClass *klass = GST_CAMERA_CONTROL_GET_CLASS(control);
+
+       if (klass->set_strobe) {
+               return klass->set_strobe(control, type, value);
+       }
+
+       return FALSE;
+}
+
+gboolean gst_camera_control_get_strobe(GstCameraControl *control, gint type, gint *value)
+{
+       GstCameraControlClass *klass = GST_CAMERA_CONTROL_GET_CLASS(control);
+
+       if (klass->get_strobe) {
+               return klass->get_strobe(control, type, value);
+       }
+
+       return FALSE;
+}
+
+gboolean gst_camera_control_set_detect(GstCameraControl *control, gint type, gint value)
+{
+       GstCameraControlClass *klass = GST_CAMERA_CONTROL_GET_CLASS(control);
+
+       if (klass->set_detect) {
+               return klass->set_detect(control, type, value);
+       }
+
+       return FALSE;
+}
+
+gboolean gst_camera_control_get_detect(GstCameraControl *control, gint type, gint *value)
+{
+       GstCameraControlClass *klass = GST_CAMERA_CONTROL_GET_CLASS(control);
+
+       if (klass->get_detect) {
+               return klass->get_detect(control, type, value);
+       }
+
+       return FALSE;
+}
+
+gboolean gst_camera_control_set_zoom(GstCameraControl *control, gint type, gint value)
+{
+       GstCameraControlClass *klass = GST_CAMERA_CONTROL_GET_CLASS(control);
+
+       if (klass->set_zoom) {
+               return klass->set_zoom(control, type, value);
+       }
+
+       return FALSE;
+}
+
+gboolean gst_camera_control_get_zoom(GstCameraControl *control, gint type, gint *value)
+{
+       GstCameraControlClass *klass = GST_CAMERA_CONTROL_GET_CLASS(control);
+
+       if (klass->get_zoom) {
+               return klass->get_zoom(control, type, value);
+       }
+
+       return FALSE;
+}
+
+gboolean gst_camera_control_set_focus(GstCameraControl *control, gint mode, gint range)
+{
+       GstCameraControlClass *klass = GST_CAMERA_CONTROL_GET_CLASS(control);
+
+       if (klass->set_focus) {
+               return klass->set_focus(control, mode, range);
+       }
+
+       return FALSE;
+}
+
+gboolean gst_camera_control_get_focus(GstCameraControl *control, gint *mode, gint *range)
+{
+       GstCameraControlClass *klass = GST_CAMERA_CONTROL_GET_CLASS(control);
+
+       if (klass->get_focus) {
+               return klass->get_focus(control, mode, range);
+       }
+
+       return FALSE;
+}
+
+gboolean gst_camera_control_start_auto_focus(GstCameraControl *control)
+{
+       GstCameraControlClass *klass = GST_CAMERA_CONTROL_GET_CLASS(control);
+
+       if (klass->start_auto_focus) {
+               return klass->start_auto_focus(control);
+       }
+
+       return FALSE;
+}
+
+gboolean gst_camera_control_stop_auto_focus(GstCameraControl *control)
+{
+       GstCameraControlClass *klass = GST_CAMERA_CONTROL_GET_CLASS(control);
+
+       if (klass->stop_auto_focus) {
+               return klass->stop_auto_focus(control);
+       }
+
+       return FALSE;
+}
+
+gboolean gst_camera_control_set_focus_level(GstCameraControl *control, gint manual_level)
+{
+       GstCameraControlClass *klass = GST_CAMERA_CONTROL_GET_CLASS(control);
+
+       if (klass->set_focus_level) {
+               return klass->set_focus_level(control, manual_level);
+       }
+
+       return FALSE;
+}
+
+gboolean gst_camera_control_get_focus_level(GstCameraControl *control, gint *manual_level)
+{
+       GstCameraControlClass *klass = GST_CAMERA_CONTROL_GET_CLASS(control);
+
+       if (klass->get_focus_level) {
+               return klass->get_focus_level(control, manual_level);
+       }
+
+       return FALSE;
+}
+
+gboolean gst_camera_control_set_auto_focus_area(GstCameraControl *control, GstCameraControlRectType rect)
+{
+       GstCameraControlClass *klass = GST_CAMERA_CONTROL_GET_CLASS(control);
+
+       if (klass->set_auto_focus_area) {
+               return klass->set_auto_focus_area(control, rect);
+       }
+
+       return FALSE;
+}
+
+gboolean gst_camera_control_get_auto_focus_area(GstCameraControl *control, GstCameraControlRectType *rect)
+{
+       GstCameraControlClass *klass = GST_CAMERA_CONTROL_GET_CLASS(control);
+
+       if (klass->get_auto_focus_area) {
+               return klass->get_auto_focus_area(control, rect);
+       }
+
+       return FALSE;
+}
+
+gboolean gst_camera_control_set_wdr(GstCameraControl *control, gint value)
+{
+       GstCameraControlClass *klass = GST_CAMERA_CONTROL_GET_CLASS(control);
+
+       if (klass->set_wdr) {
+               return klass->set_wdr(control, value);
+       }
+
+       return FALSE;
+}
+
+gboolean gst_camera_control_get_wdr(GstCameraControl *control, gint *value)
+{
+       GstCameraControlClass *klass = GST_CAMERA_CONTROL_GET_CLASS(control);
+
+       if (klass->get_wdr) {
+               return klass->get_wdr(control, value);
+       }
+
+       return FALSE;
+}
+
+gboolean gst_camera_control_set_ahs(GstCameraControl *control, gint value)
+{
+       GstCameraControlClass *klass = GST_CAMERA_CONTROL_GET_CLASS(control);
+
+       if (klass->set_ahs) {
+               return klass->set_ahs(control, value);
+       }
+
+       return FALSE;
+}
+
+gboolean gst_camera_control_get_ahs(GstCameraControl *control, gint *value)
+{
+       GstCameraControlClass *klass = GST_CAMERA_CONTROL_GET_CLASS(control);
+
+       if (klass->get_ahs) {
+               return klass->get_ahs(control, value);
+       }
+
+       return FALSE;
+}
+
+gboolean gst_camera_control_set_part_color(GstCameraControl *control, gint type, gint value)
+{
+       GstCameraControlClass *klass = GST_CAMERA_CONTROL_GET_CLASS(control);
+
+       if (klass->set_part_color) {
+               return klass->set_part_color(control, type, value);
+       }
+
+       return FALSE;
+}
+
+gboolean gst_camera_control_get_part_color(GstCameraControl *control, gint type, gint *value)
+{
+       GstCameraControlClass *klass = GST_CAMERA_CONTROL_GET_CLASS(control);
+
+       if (klass->get_part_color) {
+               return klass->get_part_color(control, type, value);
+       }
+
+       return FALSE;
+}
+
+gboolean
+gst_camera_control_get_exif_info(GstCameraControl *control, GstCameraControlExifInfo *info)
+{
+       GstCameraControlClass *klass = GST_CAMERA_CONTROL_GET_CLASS(control);
+
+       if (klass->get_exif_info) {
+               return klass->get_exif_info(control, info);
+       }
+
+       return FALSE;
+}
+
+
+gboolean gst_camera_control_get_basic_dev_info(GstCameraControl *control, gint dev_id, GstCameraControlCapsInfoType *info)
+{
+       GstCameraControlClass *klass = GST_CAMERA_CONTROL_GET_CLASS(control);
+
+       if (klass->get_basic_dev_info) {
+               return klass->get_basic_dev_info(control, dev_id, info);
+       }
+
+       return FALSE;
+}
+
+gboolean gst_camera_control_get_misc_dev_info(GstCameraControl *control, gint dev_id, GstCameraControlCtrlListInfoType *info)
+{
+       GstCameraControlClass *klass = GST_CAMERA_CONTROL_GET_CLASS( control );
+
+       if( klass->get_misc_dev_info )
+       {
+               return klass->get_misc_dev_info( control, dev_id, info );
+       }
+
+       return FALSE;
+}
+
+gboolean gst_camera_control_get_extra_dev_info(GstCameraControl *control, gint dev_id, GstCameraControlExtraInfoType *info)
+{
+       GstCameraControlClass *klass = GST_CAMERA_CONTROL_GET_CLASS(control);
+
+       if (klass->get_extra_dev_info) {
+               return klass->get_extra_dev_info(control, dev_id, info);
+       }
+
+       return FALSE;
+}
+
+void gst_camera_control_set_capture_command(GstCameraControl *control, GstCameraControlCaptureCommand cmd)
+{
+       GstCameraControlClass *klass = GST_CAMERA_CONTROL_GET_CLASS(control);
+
+       if (klass->set_capture_command) {
+               klass->set_capture_command(control, cmd);
+       }
+
+       return;
+}
+
+gboolean gst_camera_control_start_face_zoom(GstCameraControl *control, gint x, gint y, gint zoom_level)
+{
+       GstCameraControlClass *klass = GST_CAMERA_CONTROL_GET_CLASS(control);
+
+       if (klass->start_face_zoom) {
+               return klass->start_face_zoom(control, x, y, zoom_level);
+       }
+
+       return FALSE;
+}
+
+gboolean gst_camera_control_stop_face_zoom(GstCameraControl *control)
+{
+       GstCameraControlClass *klass = GST_CAMERA_CONTROL_GET_CLASS(control);
+
+       if (klass->stop_face_zoom) {
+               return klass->stop_face_zoom(control);
+       }
+
+       return FALSE;
+}
+
+void gst_camera_control_value_changed(GstCameraControl *control, GstCameraControlChannel *control_channel, gint value)
+{
+       g_signal_emit(G_OBJECT(control), gst_camera_control_signals[CONTROL_VALUE_CHANGED], 0, control_channel, value);
+       g_signal_emit_by_name(G_OBJECT(control_channel), "control-value-changed", value);
+}
diff --git a/gst-libs/gst/video/cameracontrol.h b/gst-libs/gst/video/cameracontrol.h
new file mode 100644 (file)
index 0000000..173d8b9
--- /dev/null
@@ -0,0 +1,462 @@
+/*
+ * GStreamer Camera Control Interface
+ *
+ * Copyright (c) 2000 - 2012 Samsung Electronics Co., Ltd.
+ *
+ * Contact: Jeongmo Yang <jm80.yang@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
+ *
+ */
+
+/* ===========================================================================================
+EDIT HISTORY FOR MODULE
+
+       This section contains comments describing changes made to the module.
+       Notice that changes are listed in reverse chronological order.
+
+when           who                                                     what, where, why
+---------      ------------------------        ------------------------------------------------------
+12/09/08       jm80.yang@samsung.com           Created
+
+=========================================================================================== */
+
+#ifndef __GST_CAMERA_CONTROL_H__
+#define __GST_CAMERA_CONTROL_H__
+
+#include <gst/gst.h>
+#include <gst/video/cameracontrolchannel.h>
+//#include <gst/interfaces/interfaces-enumtypes.h>
+
+G_BEGIN_DECLS
+
+#define GST_TYPE_CAMERA_CONTROL \
+       (gst_camera_control_get_type())
+#define GST_CAMERA_CONTROL(obj) \
+    (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_CAMERA_CONTROL, GstCameraControl))
+#define GST_CAMERA_CONTROL_GET_CLASS(inst) \
+       (G_TYPE_INSTANCE_GET_INTERFACE ((inst), GST_TYPE_CAMERA_CONTROL, GstCameraControlClass))
+#define GST_CAMERA_CONTROL_CLASS(klass) \
+       (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_CAMERA_CONTROL, GstCameraControlClass))
+#define GST_IS_CAMERA_CONTROL(obj) \
+    (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_CAMERA_CONTROL))
+#define GST_IS_CAMERA_CONTROL_CLASS(klass) \
+       (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_CAMERA_CONTROL))
+#define GST_CAMERA_CONTROL_TYPE(klass) (klass->camera_control_type)    
+
+
+typedef struct _GstCameraControl GstCameraControl;
+  
+typedef enum
+{
+       // TODO : V4L2 Extend
+       GST_CAMERA_CONTROL_HARDWARE,
+       GST_CAMERA_CONTROL_SOFTWARE,
+} GstCameraControlType;
+
+/**
+ * Enumerations for Camera control Exposure types.
+ */
+typedef enum
+{
+       GST_CAMERA_CONTROL_F_NUMBER,
+       GST_CAMERA_CONTROL_SHUTTER_SPEED,
+       GST_CAMERA_CONTROL_ISO,
+       GST_CAMERA_CONTROL_PROGRAM_MODE,
+       GST_CAMERA_CONTROL_EXPOSURE_MODE,
+       GST_CAMERA_CONTROL_EXPOSURE_VALUE,
+} GstCameraControlExposureType;
+
+/**
+ * Enumerations for Camera control Capture mode types.
+ */
+typedef enum
+{
+       GST_CAMERA_CONTROL_CAPTURE_MODE,
+       GST_CAMERA_CONTROL_OUTPUT_MODE,
+       GST_CAMERA_CONTROL_FRAME_COUNT,
+       GST_CAMERA_CONTROL_JPEG_QUALITY,
+} GstCameraControlCaptureModeType;
+
+/**
+ * Enumerations for Capture mode types.
+ */
+typedef enum
+{
+       CAPTURE_MODE_SINGLE_SHOT,
+       CAPTURE_MODE_MULTI_SHOT,
+       CAPTURE_MODE_ANTI_HANDSHAKE,
+} CaptureModeType;
+
+/**
+ * Enumerations for Camera control Strobe types.
+ */
+typedef enum
+{
+       GST_CAMERA_CONTROL_STROBE_CONTROL,
+       GST_CAMERA_CONTROL_STROBE_CAPABILITIES,
+       GST_CAMERA_CONTROL_STROBE_MODE,
+       GST_CAMERA_CONTROL_STROBE_STATUS,
+       GST_CAMERA_CONTROL_STROBE_EV,
+} GstCameraControlStrobeType;
+
+/**
+ * Enumerations for Camera control Face detection types.
+ */
+typedef enum
+{
+       GST_CAMERA_CONTROL_FACE_DETECT_MODE,
+       GST_CAMERA_CONTROL_FACE_DETECT_NUMBER,
+       GST_CAMERA_CONTROL_FACE_FOCUS_SELECT,
+       GST_CAMERA_CONTROL_FACE_SELECT_NUMBER,
+       GST_CAMERA_CONTROL_FACE_DETECT_STATUS,
+} GstCameraControlFaceDetectType;
+
+/**
+ * Enumerations for Camera control Zoom types.
+ */
+typedef enum
+{
+       GST_CAMERA_CONTROL_DIGITAL_ZOOM,
+       GST_CAMERA_CONTROL_OPTICAL_ZOOM,
+} GstCameraControlZoomType;
+
+/**
+ * Enumerations for Camera control Part color.
+ */
+typedef enum
+{
+       GST_CAMERA_CONTROL_PART_COLOR_SRC,
+       GST_CAMERA_CONTROL_PART_COLOR_DST,
+       GST_CAMERA_CONTROL_PART_COLOR_MODE,     
+} GstCameraControlPartColorType;
+
+/**
+ * Enumerations for Camera capture command.
+ */
+typedef enum
+{
+       GST_CAMERA_CONTROL_CAPTURE_COMMAND_NONE,
+       GST_CAMERA_CONTROL_CAPTURE_COMMAND_START,
+       GST_CAMERA_CONTROL_CAPTURE_COMMAND_STOP,
+       GST_CAMERA_CONTROL_CAPTURE_COMMAND_STOP_MULTISHOT,
+} GstCameraControlCaptureCommand;
+
+
+
+/////////////////////////////////
+//  For Query functionalities  //
+//  For Querying capabilities  //
+/////////////////////////////////
+/*! Use static size of structures for querying because of performance
+ */
+/**
+ * Don't modify this sizes
+ * If want to modify this size, consider also under layer structure size
+ */
+#define MAX_NUM_FMT_DESC        32
+#define MAX_NUM_RESOLUTION      32
+#define MAX_NUM_AVAILABLE_TPF   16
+#define MAX_NUM_AVAILABLE_FPS   16
+#define MAX_NUM_CTRL_LIST_INFO  64
+#define MAX_NUM_CTRL_MENU       64
+#define MAX_NUM_DETECTED_FACES  16
+#define MAX_SZ_CTRL_NAME_STRING 32
+#define MAX_SZ_DEV_NAME_STRING  32
+
+/*! @struct GstCameraControlFracType
+ *  @brief For timeperframe as fraction type
+ *  Elapse time consumed by one frame, reverse of FPS
+ */
+typedef struct _GstCameraControlFracType {
+       gint num;
+       gint den;
+} GstCameraControlFracType;
+
+/*! @struct GstCameraControlRectType
+ *  @brief For touch auto focusing area and face detection area
+ */
+typedef struct _GstCameraControlRectType {
+       gint x;
+       gint y;
+       gint width;
+       gint height;
+} GstCameraControlRectType;
+
+/*! @struct GstCameraControlResolutionType
+ *  @brief For querying supported resolutions
+ */
+typedef struct _GstCameraControlResolutionType {
+    gint w;
+    gint h;
+
+    /* Available time per frame(tpf) as each pixelformat */
+    gint num_avail_tpf;
+    GstCameraControlFracType tpf[MAX_NUM_AVAILABLE_TPF];
+} GstCameraControlResolutionType;
+
+/*! @struct GstCameraControlFraction
+ *  @brief Time per frame or frame per second will be expressed by this structure
+ *  Time per frame or frame per second will be expressed by this structure
+ */
+typedef struct _GstCameraControlFraction {
+    int numerator;             /**< Upper number of fraction*/
+    int denominator;           /**< Lower number of fraction*/
+} GstCameraControlFraction;
+
+/*! @struct GstCameraControlFmtDescType
+ *  @brief For querying supported format type
+ */
+typedef struct _GstCameraControlFmtDescType {
+    /* fourcc name of each pixelformat */
+    guint fcc;
+    gint fcc_use;
+
+    /* Available resolutions as each pixelformat */
+    gint num_resolution;
+    GstCameraControlResolutionType resolutions[MAX_NUM_RESOLUTION];
+} GstCameraControlFmtDescType;
+
+/*! @struct GstCameraControlCapsInfoType
+ *  @brief For querying image input capabilities
+ */
+typedef struct _GstCameraControlCapsInfoType {
+    char dev_name[MAX_SZ_DEV_NAME_STRING];
+    int input_idx;
+    gint num_fmt_desc;
+    GstCameraControlFmtDescType fmt_desc[MAX_NUM_FMT_DESC];
+
+    int num_preview_resolution;
+    int preview_resolution_width[MAX_NUM_RESOLUTION];
+    int preview_resolution_height[MAX_NUM_RESOLUTION];
+
+    int num_capture_resolution;
+    int capture_resolution_width[MAX_NUM_RESOLUTION];
+    int capture_resolution_height[MAX_NUM_RESOLUTION];
+
+    int num_preview_fmt;
+    unsigned int preview_fmt[MAX_NUM_FMT_DESC];
+
+    int num_capture_fmt;
+    unsigned int capture_fmt[MAX_NUM_FMT_DESC];
+
+    int num_fps;
+    GstCameraControlFraction fps[MAX_NUM_AVAILABLE_FPS];
+} GstCameraControlCapsInfoType;
+
+/*! @struct GstCameraControlFaceInfo
+ *  @brief For face information
+ */
+typedef struct _GstCameraControlFaceInfo {
+       int id;
+       int score;
+       GstCameraControlRectType rect;
+} GstCameraControlFaceInfo;
+
+/*! @struct GstCameraControlFaceDetectInfo
+ *  @brief For face detect information
+ */
+typedef struct _GstCameraControlFaceDetectInfo {
+       int num_of_faces;
+       GstCameraControlFaceInfo face_info[MAX_NUM_DETECTED_FACES];
+} GstCameraControlFaceDetectInfo;
+
+/////////////////////////////
+//  For Querying controls  //
+/////////////////////////////
+enum {
+    GST_CAMERA_CTRL_TYPE_RANGE = 0,
+    GST_CAMERA_CTRL_TYPE_BOOL,
+    GST_CAMERA_CTRL_TYPE_ARRAY,
+    GST_CAMERA_CTRL_TYPE_UNKNOWN,
+    GST_CAMERA_CTRL_TYPE_NUM,
+};
+
+/*! @struct GstCameraControlCtrlMenuType
+ *  @brief For querying menu of specified controls
+ */
+typedef struct _GstCameraControlCtrlMenuType {
+    gint menu_index;
+    gchar menu_name[MAX_SZ_CTRL_NAME_STRING];
+} GstCameraControlCtrlMenuType;
+
+/*! @struct GstCameraControlCtrlInfoType
+ *  @brief For querying controls detail
+ */
+typedef struct _GstCameraControlCtrlInfoType {
+    gint avsys_ctrl_id;
+    gint v4l2_ctrl_id;
+    gint ctrl_type;
+    gchar ctrl_name[MAX_SZ_CTRL_NAME_STRING];
+    gint min;
+    gint max;
+    gint step;
+    gint default_val;
+    gint num_ctrl_menu;
+    GstCameraControlCtrlMenuType ctrl_menu[MAX_NUM_CTRL_MENU];
+} GstCameraControlCtrlInfoType;
+
+/*! @struct GstCameraControlCtrlListInfoType
+ *  @brief For querying controls
+ */
+typedef struct _GstCameraControlCtrlListInfoType {
+    gint num_ctrl_list_info;
+    GstCameraControlCtrlInfoType ctrl_info[MAX_NUM_CTRL_LIST_INFO];
+} GstCameraControlCtrlListInfoType;
+
+/* capabilities field */
+#define GST_CAMERA_STROBE_CAP_NONE              0x0000 /* No strobe supported */
+#define GST_CAMERA_STROBE_CAP_OFF               0x0001 /* Always flash off mode */
+#define GST_CAMERA_STROBE_CAP_ON                0x0002 /* Always use flash light mode */
+#define GST_CAMERA_STROBE_CAP_AUTO              0x0004 /* Flashlight works automatic */
+#define GST_CAMERA_STROBE_CAP_REDEYE            0x0008 /* Red-eye reduction */
+#define GST_CAMERA_STROBE_CAP_SLOWSYNC          0x0010 /* Slow sync */
+#define GST_CAMERA_STROBE_CAP_FRONT_CURTAIN     0x0020 /* Front curtain */
+#define GST_CAMERA_STROBE_CAP_REAR_CURTAIN      0x0040 /* Rear curtain */
+#define GST_CAMERA_STROBE_CAP_PERMANENT         0x0080 /* keep turned on until turning off */
+#define GST_CAMERA_STROBE_CAP_EXTERNAL          0x0100 /* use external strobe */
+
+typedef struct _GstCameraControlExtraInfoType {
+    guint strobe_caps;                                   /**< Use above caps field */
+    guint detection_caps;                                /**< Just boolean */
+    guint reserved[4];
+} GstCameraControlExtraInfoType;
+/////////////////////////////////////
+//  END For Query functionalities  //
+/////////////////////////////////////
+
+
+/**
+ * Enumerations for Camera control Part color.
+ */
+typedef struct _GstCameraControlExifInfo {
+       /* Dynamic value */
+       guint32 exposure_time_numerator;    /* Exposure time, given in seconds */
+       guint32 exposure_time_denominator;
+       gint shutter_speed_numerator;       /* Shutter speed, given in APEX(Additive System Photographic Exposure) */
+       gint shutter_speed_denominator;
+       gint brigtness_numerator;           /* Value of brightness, before firing flash, given in APEX value */
+       gint brightness_denominator;
+       guint16 iso;                        /* Sensitivity value of sensor */
+       guint16 flash;                      /* Whether flash is fired(1) or not(0) */
+       gint metering_mode;                 /* metering mode in EXIF 2.2 */
+       gint exif_image_width;              /* Size of image */
+       gint exif_image_height;
+       gint exposure_bias_in_APEX;         /* Exposure bias in APEX standard */
+       gint software_used;                 /* Firmware S/W version */
+
+       /* Fixed value */
+       gint component_configuration;       /* color components arrangement */
+       gint colorspace;                    /* colorspace information */
+       gint focal_len_numerator;           /* Lens focal length */
+       gint focal_len_denominator;
+       gint aperture_f_num_numerator;      /* Aperture value */
+       gint aperture_f_num_denominator;
+       gint aperture_in_APEX;              /* Aperture value in APEX standard */
+       gint max_lens_aperture_in_APEX;     /* Max aperture value in APEX standard */
+} GstCameraControlExifInfo;
+
+
+typedef struct _GstCameraControlClass {
+       GTypeInterface klass;
+       GstCameraControlType camera_control_type;
+
+       /* virtual functions */
+       const GList*(*list_channels)                   (GstCameraControl *control);
+
+       gboolean        (*set_value)                   (GstCameraControl *control, GstCameraControlChannel *control_channel);
+       gboolean        (*get_value)                   (GstCameraControl *control, GstCameraControlChannel *control_channel);
+       gboolean        (*set_exposure)                (GstCameraControl *control, gint type, gint value1, gint value2);
+       gboolean        (*get_exposure)                (GstCameraControl *control, gint type, gint *value1, gint *value2);
+       gboolean        (*set_capture_mode)            (GstCameraControl *control, gint type, gint value);
+       gboolean        (*get_capture_mode)            (GstCameraControl *control, gint type, gint *value);
+       gboolean        (*set_strobe)                  (GstCameraControl *control, gint type, gint value);
+       gboolean        (*get_strobe)                  (GstCameraControl *control, gint type, gint *value);
+       gboolean        (*set_detect)                  (GstCameraControl *control, gint type, gint value);
+       gboolean        (*get_detect)                  (GstCameraControl *control, gint type, gint *value);
+       gboolean        (*set_zoom)                    (GstCameraControl *control, gint type, gint value);
+       gboolean        (*get_zoom)                    (GstCameraControl *control, gint type, gint *value);
+       gboolean        (*set_focus)                   (GstCameraControl *control, gint mode, gint range);
+       gboolean        (*get_focus)                   (GstCameraControl *control, gint *mode, gint *range);
+       gboolean        (*start_auto_focus)            (GstCameraControl *control);
+       gboolean        (*stop_auto_focus)             (GstCameraControl *control);
+       gboolean        (*set_focus_level)             (GstCameraControl *control, gint manual_level);
+       gboolean        (*get_focus_level)             (GstCameraControl *control, gint *manual_level);
+       gboolean        (*set_auto_focus_area)         (GstCameraControl *control, GstCameraControlRectType rect);
+       gboolean        (*get_auto_focus_area)         (GstCameraControl *control, GstCameraControlRectType *rect);
+       gboolean        (*set_wdr)                     (GstCameraControl *control, gint value);
+       gboolean        (*get_wdr)                     (GstCameraControl *control, gint *value);
+       gboolean        (*set_ahs)                     (GstCameraControl *control, gint value);
+       gboolean        (*get_ahs)                     (GstCameraControl *control, gint *value);
+       gboolean        (*set_part_color)              (GstCameraControl *control, gint type, gint value);
+       gboolean        (*get_part_color)              (GstCameraControl *control, gint type, gint *value);
+       gboolean        (*get_exif_info)               (GstCameraControl *control, GstCameraControlExifInfo *info);
+       gboolean        (*get_basic_dev_info)          (GstCameraControl *control, gint dev_id, GstCameraControlCapsInfoType *info);
+       gboolean        (*get_misc_dev_info)           (GstCameraControl *control, gint dev_id, GstCameraControlCtrlListInfoType *info);
+       gboolean        (*get_extra_dev_info)          (GstCameraControl *control, gint dev_id, GstCameraControlExtraInfoType *info);
+       void            (*set_capture_command)         (GstCameraControl *control, GstCameraControlCaptureCommand cmd);
+       gboolean        (*start_face_zoom)             (GstCameraControl *control, gint x, gint y, gint zoom_level);
+       gboolean        (*stop_face_zoom)              (GstCameraControl *control);
+
+       /* signals */
+       void (* value_changed)                          (GstCameraControl *control, GstCameraControlChannel *channel, gint value);
+} GstCameraControlClass;
+
+GType gst_camera_control_get_type(void);
+
+/* virtual class function wrappers */
+const GList*   gst_camera_control_list_channels        (GstCameraControl *control);
+
+gboolean       gst_camera_control_set_value            (GstCameraControl *control, GstCameraControlChannel *control_channel);
+gboolean       gst_camera_control_get_value            (GstCameraControl *control, GstCameraControlChannel *control_channel);
+gboolean       gst_camera_control_set_exposure         (GstCameraControl *control, gint type, gint value1, gint value2);
+gboolean       gst_camera_control_get_exposure         (GstCameraControl *control, gint type, gint *value1, gint *value2);
+gboolean       gst_camera_control_set_capture_mode     (GstCameraControl *control, gint type, gint value);
+gboolean       gst_camera_control_get_capture_mode     (GstCameraControl *control, gint type, gint *value);
+gboolean       gst_camera_control_set_strobe           (GstCameraControl *control, gint type, gint value);
+gboolean       gst_camera_control_get_strobe           (GstCameraControl *control, gint type, gint *value);
+gboolean       gst_camera_control_set_detect           (GstCameraControl *control, gint type, gint value);
+gboolean       gst_camera_control_get_detect           (GstCameraControl *control, gint type, gint *value);
+gboolean       gst_camera_control_set_zoom             (GstCameraControl *control, gint type, gint value);
+gboolean       gst_camera_control_get_zoom             (GstCameraControl *control, gint type, gint *value);
+gboolean       gst_camera_control_set_focus            (GstCameraControl *control, gint mode, gint range);
+gboolean       gst_camera_control_get_focus            (GstCameraControl *control, gint *mode, gint *range);
+gboolean       gst_camera_control_start_auto_focus     (GstCameraControl *control);
+gboolean       gst_camera_control_stop_auto_focus      (GstCameraControl *control);
+gboolean       gst_camera_control_set_focus_level      (GstCameraControl *control, gint manual_level);
+gboolean       gst_camera_control_get_focus_level      (GstCameraControl *control, gint *manual_level);
+gboolean       gst_camera_control_set_auto_focus_area  (GstCameraControl *control, GstCameraControlRectType rect);
+gboolean       gst_camera_control_get_auto_focus_area  (GstCameraControl *control, GstCameraControlRectType *rect);
+gboolean       gst_camera_control_set_wdr              (GstCameraControl *control, gint value);
+gboolean       gst_camera_control_get_wdr              (GstCameraControl *control, gint *value);
+gboolean       gst_camera_control_set_ahs              (GstCameraControl *control, gint value);
+gboolean       gst_camera_control_get_ahs              (GstCameraControl *control, gint *value);
+gboolean       gst_camera_control_set_part_color       (GstCameraControl *control, gint type, gint value);
+gboolean       gst_camera_control_get_part_color       (GstCameraControl *control, gint type, gint *value);
+gboolean       gst_camera_control_get_exif_info        (GstCameraControl *control, GstCameraControlExifInfo *info);
+gboolean       gst_camera_control_get_basic_dev_info   (GstCameraControl *control, gint dev_id, GstCameraControlCapsInfoType *info);
+gboolean       gst_camera_control_get_misc_dev_info    (GstCameraControl *control, gint dev_id, GstCameraControlCtrlListInfoType *info);
+gboolean       gst_camera_control_get_extra_dev_info   (GstCameraControl *control, gint dev_id, GstCameraControlExtraInfoType *info);
+void           gst_camera_control_set_capture_command  (GstCameraControl *control, GstCameraControlCaptureCommand cmd);
+gboolean       gst_camera_control_start_face_zoom      (GstCameraControl *control, gint x, gint y, gint zoom_level);
+gboolean       gst_camera_control_stop_face_zoom       (GstCameraControl *control);
+
+
+/* trigger signal */
+void           gst_camera_control_value_changed        (GstCameraControl *control, GstCameraControlChannel *control_channel, gint value);
+
+G_END_DECLS
+
+#endif /* __GST_CAMERA_CONTROL_H__ */
diff --git a/gst-libs/gst/video/cameracontrolchannel.c b/gst-libs/gst/video/cameracontrolchannel.c
new file mode 100644 (file)
index 0000000..86c7ce9
--- /dev/null
@@ -0,0 +1,112 @@
+/* GStreamer Camera Control Channel Interface
+ *
+ * Copyright (c) 2000 - 2012 Samsung Electronics Co., Ltd.
+ *
+ * Contact: Jeongmo Yang <jm80.yang@samsung.com>
+ *
+ * cameracontrolchannel.c: cameracontrol channel object design
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "cameracontrolchannel.h"
+
+enum {
+       /* FILL ME */
+       SIGNAL_VALUE_CHANGED,
+       LAST_SIGNAL
+};
+
+static void gst_camera_control_channel_class_init(GstCameraControlChannelClass* klass);
+static void gst_camera_control_channel_init(GstCameraControlChannel* control_channel);
+static void gst_camera_control_channel_dispose(GObject* object);
+
+static GObjectClass *parent_class = NULL;
+static guint signals[LAST_SIGNAL] = { 0 };
+
+GType gst_camera_control_channel_get_type(void)
+{
+       static GType gst_camera_control_channel_type = 0;
+
+       if (!gst_camera_control_channel_type) {
+               static const GTypeInfo camera_control_channel_info = {
+                       sizeof (GstCameraControlChannelClass),
+                       NULL,
+                       NULL,
+                       (GClassInitFunc) gst_camera_control_channel_class_init,
+                       NULL,
+                       NULL,
+                       sizeof (GstCameraControlChannel),
+                       0,
+                       (GInstanceInitFunc) gst_camera_control_channel_init,
+                       NULL
+               };
+
+               gst_camera_control_channel_type = \
+                       g_type_register_static(G_TYPE_OBJECT,
+                                              "GstCameraControlChannel",
+                                              &camera_control_channel_info,
+                                              0);
+       }
+
+       return gst_camera_control_channel_type;
+}
+
+static void gst_camera_control_channel_class_init(GstCameraControlChannelClass* klass)
+{
+       GObjectClass *object_klass = (GObjectClass*) klass;
+
+       parent_class = g_type_class_peek_parent (klass);
+
+       signals[SIGNAL_VALUE_CHANGED] = \
+               g_signal_new("control-value-changed",
+                            G_TYPE_FROM_CLASS (klass),
+                            G_SIGNAL_RUN_LAST,
+                            G_STRUCT_OFFSET (GstCameraControlChannelClass, value_changed),
+                            NULL,
+                            NULL,
+                            g_cclosure_marshal_VOID__INT,
+                            G_TYPE_NONE,
+                            1,
+                            G_TYPE_INT);
+
+       object_klass->dispose = gst_camera_control_channel_dispose;
+}
+
+static void gst_camera_control_channel_init(GstCameraControlChannel* control_channel)
+{
+       control_channel->label = NULL;
+       control_channel->min_value = control_channel->max_value = 0;
+}
+
+static void gst_camera_control_channel_dispose(GObject* object)
+{
+       GstCameraControlChannel *control_channel = GST_CAMERA_CONTROL_CHANNEL(object);
+
+       if (control_channel->label) {
+               g_free (control_channel->label);
+       }
+
+       control_channel->label = NULL;
+
+       if (parent_class->dispose) {
+               parent_class->dispose (object);
+       }
+}
diff --git a/gst-libs/gst/video/cameracontrolchannel.h b/gst-libs/gst/video/cameracontrolchannel.h
new file mode 100644 (file)
index 0000000..d8a2979
--- /dev/null
@@ -0,0 +1,65 @@
+/* GStreamer Camera Control Channel Interface
+ *
+ * Copyright (c) 2000 - 2012 Samsung Electronics Co., Ltd.
+ *
+ * Contact: Jeongmo Yang <jm80.yang@samsung.com>
+ *
+ * cameracontrolchannel.h: individual channel object
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __GST_CAMERA_CONTROL_CHANNEL_H__
+#define __GST_CAMERA_CONTROL_CHANNEL_H__
+
+#include <gst/gst.h>
+
+G_BEGIN_DECLS
+
+#define GST_TYPE_CAMERA_CONTROL_CHANNEL \
+  (gst_camera_control_channel_get_type ())
+#define GST_CAMERA_CONTROL_CHANNEL(obj) \
+  (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_CAMERA_CONTROL_CHANNEL, \
+                               GstCameraControlChannel))
+#define GST_CAMERA_CONTROL_CHANNEL_CLASS(klass) \
+  (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_CAMERA_CONTROL_CHANNEL, \
+                            GstCameraControlChannelClass))
+#define GST_IS_CAMERA_CONTROL_CHANNEL(obj) \
+  (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_CAMERA_CONTROL_CHANNEL))
+#define GST_IS_CAMERA_CONTROL_CHANNEL_CLASS(klass) \
+  (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_CAMERA_CONTROL_CHANNEL))
+
+typedef struct _GstCameraControlChannel {
+       GObject parent;
+       gchar *label;
+       gint min_value;
+       gint max_value;
+} GstCameraControlChannel;
+
+typedef struct _GstCameraControlChannelClass {
+       GObjectClass parent;
+
+       /* signals */
+       void (*value_changed)(GstCameraControlChannel *control_channel, gint value);
+
+       gpointer _gst_reserved[GST_PADDING];
+} GstCameraControlChannelClass;
+
+GType gst_camera_control_channel_get_type(void);
+
+G_END_DECLS
+
+#endif /* __GST_CAMERA_CONTROL_CHANNEL_H__ */
index fed5314..3c7183c 100644 (file)
@@ -2329,6 +2329,8 @@ static VideoFormat formats[] = {
       DPTH888, PSTR244, PLANE0, OFFS013, SUB422, PACK_YUY2),
   MAKE_YUV_FORMAT (UYVY, "raw video", GST_MAKE_FOURCC ('U', 'Y', 'V', 'Y'),
       DPTH888, PSTR244, PLANE0, OFFS102, SUB422, PACK_UYVY),
+  MAKE_YUV_FORMAT (ITLV, "raw video", GST_MAKE_FOURCC ('I', 'T', 'L', 'V'),
+      DPTH888, PSTR244, PLANE0, OFFS012, SUB422, PACK_UYVY),
   MAKE_YUVA_PACK_FORMAT (AYUV, "raw video", GST_MAKE_FOURCC ('A', 'Y', 'U',
           'V'), DPTH8888, PSTR4444, PLANE0, OFFS1230, SUB4444, PACK_AYUV),
   MAKE_RGB_FORMAT (RGBx, "raw video", DPTH888, PSTR444, PLANE0, OFFS012,
@@ -2366,6 +2368,10 @@ static VideoFormat formats[] = {
       DPTH16_16_16, PSTR488, PLANE0, OFFS204, SUB422, PACK_v216),
   MAKE_YUV_FORMAT (NV12, "raw video", GST_MAKE_FOURCC ('N', 'V', '1', '2'),
       DPTH888, PSTR122, PLANE011, OFFS001, SUB420, PACK_NV12),
+  MAKE_YUV_FORMAT (SN12, "raw video", GST_MAKE_FOURCC ('S', 'N', '1', '2'),
+      DPTH888, PSTR122, PLANE011, OFFS001, SUB420, PACK_NV12),
+  MAKE_YUV_FORMAT (ST12, "raw video", GST_MAKE_FOURCC ('S', 'T', '1', '2'),
+      DPTH888, PSTR122, PLANE011, OFFS001, SUB420, PACK_NV12),
   MAKE_YUV_FORMAT (NV21, "raw video", GST_MAKE_FOURCC ('N', 'V', '2', '1'),
       DPTH888, PSTR122, PLANE011, OFFS010, SUB420, PACK_NV21),
 
@@ -2638,6 +2644,8 @@ gst_video_format_from_fourcc (guint32 fourcc)
       return GST_VIDEO_FORMAT_YVYU;
     case GST_MAKE_FOURCC ('U', 'Y', 'V', 'Y'):
       return GST_VIDEO_FORMAT_UYVY;
+    case GST_MAKE_FOURCC ('I', 'T', 'L', 'V'):
+      return GST_VIDEO_FORMAT_ITLV;
     case GST_MAKE_FOURCC ('A', 'Y', 'U', 'V'):
       return GST_VIDEO_FORMAT_AYUV;
     case GST_MAKE_FOURCC ('Y', '4', '1', 'B'):
@@ -2652,6 +2660,10 @@ gst_video_format_from_fourcc (guint32 fourcc)
       return GST_VIDEO_FORMAT_v216;
     case GST_MAKE_FOURCC ('N', 'V', '1', '2'):
       return GST_VIDEO_FORMAT_NV12;
+    case GST_MAKE_FOURCC ('S', 'N', '1', '2'):
+      return GST_VIDEO_FORMAT_SN12;
+    case GST_MAKE_FOURCC ('S', 'T', '1', '2'):
+      return GST_VIDEO_FORMAT_ST12;
     case GST_MAKE_FOURCC ('N', 'V', '2', '1'):
       return GST_VIDEO_FORMAT_NV21;
     case GST_MAKE_FOURCC ('N', 'V', '1', '6'):
index e51c70d..b079e24 100644 (file)
@@ -96,6 +96,7 @@ typedef enum {
   GST_VIDEO_FORMAT_YV12,
   GST_VIDEO_FORMAT_YUY2,
   GST_VIDEO_FORMAT_UYVY,
+  GST_VIDEO_FORMAT_ITLV,
   GST_VIDEO_FORMAT_AYUV,
   GST_VIDEO_FORMAT_RGBx,
   GST_VIDEO_FORMAT_BGRx,
@@ -114,6 +115,8 @@ typedef enum {
   GST_VIDEO_FORMAT_v210,
   GST_VIDEO_FORMAT_v216,
   GST_VIDEO_FORMAT_NV12,
+  GST_VIDEO_FORMAT_SN12,
+  GST_VIDEO_FORMAT_ST12,
   GST_VIDEO_FORMAT_NV21,
   GST_VIDEO_FORMAT_GRAY8,
   GST_VIDEO_FORMAT_GRAY16_BE,
index 52c9b12..c94ca00 100644 (file)
@@ -380,6 +380,7 @@ fill_planes (GstVideoInfo * info)
 
   switch (info->finfo->format) {
     case GST_VIDEO_FORMAT_YUY2:
+    case GST_VIDEO_FORMAT_ITLV:
     case GST_VIDEO_FORMAT_YVYU:
     case GST_VIDEO_FORMAT_UYVY:
       info->stride[0] = GST_ROUND_UP_4 (width * 2);
@@ -503,6 +504,8 @@ fill_planes (GstVideoInfo * info)
       info->size = info->stride[0] * height * 3;
       break;
     case GST_VIDEO_FORMAT_NV12:
+    case GST_VIDEO_FORMAT_SN12:
+    case GST_VIDEO_FORMAT_ST12:
     case GST_VIDEO_FORMAT_NV21:
       info->stride[0] = GST_ROUND_UP_4 (width);
       info->stride[1] = info->stride[0];
index f5a2d42..63b5a1b 100644 (file)
@@ -1692,6 +1692,22 @@ update_colorbalance (GstPlaySink * playsink)
   gst_object_unref (balance);
 }
 
+#ifdef GST_EXT_LINK_FIMCCONVERT
+static gint
+compare_name (GstElement * element, const gchar * name)
+{
+  gchar *str;
+  GST_OBJECT_LOCK (element);
+  str = g_strrstr(GST_ELEMENT_NAME (element), name);
+  GST_OBJECT_UNLOCK (element);
+
+  if (str)
+    return 0;
+  else
+    return -1;
+}
+#endif
+
 /* make the element (bin) that contains the elements needed to perform
  * video display.
  *
@@ -1712,6 +1728,7 @@ gen_video_chain (GstPlaySink * playsink, gboolean raw, gboolean async)
   GstBin *bin;
   GstPad *pad;
   GstElement *head = NULL, *prev = NULL, *elem = NULL;
+  GstPlugin *p;
 
   chain = g_new0 (GstPlayVideoChain, 1);
   chain->chain.playsink = playsink;
@@ -1876,9 +1893,22 @@ gen_video_chain (GstPlaySink * playsink, gboolean raw, gboolean async)
         && (playsink->flags & GST_PLAY_FLAG_SOFT_COLORBALANCE);
 
     GST_DEBUG_OBJECT (playsink, "creating videoconverter");
+#ifdef GST_EXT_LINK_FIMCCONVERT
+    GstIterator *iter = gst_bin_iterate_recurse (gst_element_get_parent(playsink));
+    GValue val;
+    gboolean e = gst_iterator_find_custom (iter, (GCompareFunc) compare_name, &val, "omx");
+    gst_iterator_free (iter);
+    if (e) {
+      chain->conv = gst_element_factory_make ("fimcconvert", "vconv");
+      gst_object_unref(p);
+    } else
+      chain->conv = gst_element_factory_make (COLORSPACE, "vconv");
+#else
     chain->conv =
         g_object_new (GST_TYPE_PLAY_SINK_VIDEO_CONVERT, "name", "vconv",
         "use-converters", use_converters, "use-balance", use_balance, NULL);
+#endif
+
 
     GST_OBJECT_LOCK (playsink);
     if (use_balance && GST_PLAY_SINK_VIDEO_CONVERT (chain->conv)->balance) {
index 9ec330c..676f250 100644 (file)
@@ -689,6 +689,31 @@ mid_type_find (GstTypeFind * tf, gpointer unused)
     gst_type_find_suggest (tf, GST_TYPE_FIND_MAXIMUM, MID_CAPS);
 }
 
+#ifdef GST_EXT_MIME_TYPES
+/*** audio/xmf ***/
+
+static GstStaticCaps xmf_caps = GST_STATIC_CAPS ("audio/xmf");
+
+#define XMF_CAPS gst_static_caps_get(&xmf_caps)
+static void
+xmf_type_find (GstTypeFind * tf, gpointer unused)
+{
+  guint8 *data = NULL;
+
+  /* Search FileId "XMF_" 4 bytes */
+  data = gst_type_find_peek (tf, 0, 4);
+  if (data && data[0] == 'X' && data[1] == 'M' && data[2] == 'F'
+      && data[3] == '_') {
+    /* Search Format version "2.00" 4 bytes */
+    data = gst_type_find_peek (tf, 4, 4);
+    if (data && data[0] == '1' && data[1] == '.' && data[2] == '0'
+        && data[3] == '0') {
+        gst_type_find_suggest (tf, GST_TYPE_FIND_MAXIMUM, XMF_CAPS);
+    }
+  }
+}
+#endif
+
 /*** audio/mobile-xmf ***/
 
 static GstStaticCaps mxmf_caps = GST_STATIC_CAPS ("audio/mobile-xmf");
@@ -716,6 +741,25 @@ mxmf_type_find (GstTypeFind * tf, gpointer unused)
   }
 }
 
+#ifdef GST_EXT_MIME_TYPES
+/*** audio/x-smaf ***/
+static GstStaticCaps mmf_caps = GST_STATIC_CAPS ("audio/x-smaf");
+
+#define MMF_CAPS gst_static_caps_get(&mmf_caps)
+static void
+mmf_type_find (GstTypeFind * tf, gpointer unused)
+{
+  guint8 *data = NULL;
+
+  /* http://jedi.ks.uiuc.edu/~johns/links/music/midifile.html      */
+  /* Search FileId "MMMD" 4 bytes */
+  data = gst_type_find_peek (tf, 0, 4);
+  if (data && data[0] == 'M' && data[1] == 'M' && data[2] == 'M'
+      && data[3] == 'D') {
+        gst_type_find_suggest (tf, GST_TYPE_FIND_MAXIMUM, MMF_CAPS);
+  }
+}
+#endif
 
 /*** video/x-fli ***/
 
@@ -5427,12 +5471,15 @@ plugin_init (GstPlugin * plugin)
       "asf,wm,wma,wmv",
       "\060\046\262\165\216\146\317\021\246\331\000\252\000\142\316\154", 16,
       GST_TYPE_FIND_MAXIMUM);
+#ifndef GST_EXT_MIME_TYPES
   TYPE_FIND_REGISTER (plugin, "audio/x-musepack", GST_RANK_PRIMARY,
       musepack_type_find, "mpc,mpp,mp+", MUSEPACK_CAPS, NULL, NULL);
   TYPE_FIND_REGISTER (plugin, "audio/x-au", GST_RANK_MARGINAL,
       au_type_find, "au,snd", AU_CAPS, NULL, NULL);
+#endif
   TYPE_FIND_REGISTER_RIFF (plugin, "video/x-msvideo", GST_RANK_PRIMARY,
       "avi", "AVI ");
+#ifndef GST_EXT_MIME_TYPES
   TYPE_FIND_REGISTER_RIFF (plugin, "audio/qcelp", GST_RANK_PRIMARY,
       "qcp", "QLCM");
   TYPE_FIND_REGISTER_RIFF (plugin, "video/x-cdxa", GST_RANK_PRIMARY,
@@ -5440,6 +5487,7 @@ plugin_init (GstPlugin * plugin)
   TYPE_FIND_REGISTER_START_WITH (plugin, "video/x-vcd", GST_RANK_PRIMARY,
       "dat", "\000\377\377\377\377\377\377\377\377\377\377\000", 12,
       GST_TYPE_FIND_MAXIMUM);
+#endif
   TYPE_FIND_REGISTER_START_WITH (plugin, "audio/x-imelody", GST_RANK_PRIMARY,
       "imy,ime,imelody", "BEGIN:IMELODY", 13, GST_TYPE_FIND_MAXIMUM);
 #if 0
@@ -5448,16 +5496,25 @@ plugin_init (GstPlugin * plugin)
 #endif
   TYPE_FIND_REGISTER (plugin, "audio/midi", GST_RANK_PRIMARY, mid_type_find,
       "mid,midi", MID_CAPS, NULL, NULL);
+#ifdef GST_EXT_MIME_TYPES
+  TYPE_FIND_REGISTER (plugin, "audio/xmf", GST_RANK_PRIMARY,
+      xmf_type_find, "xmf", XMF_CAPS, NULL, NULL);
+  TYPE_FIND_REGISTER (plugin, "audio/x-smaf", GST_RANK_PRIMARY,
+      mmf_type_find, "mmf", MMF_CAPS, NULL, NULL);
+#endif
   TYPE_FIND_REGISTER_RIFF (plugin, "audio/riff-midi", GST_RANK_PRIMARY,
       "mid,midi", "RMID");
   TYPE_FIND_REGISTER (plugin, "audio/mobile-xmf", GST_RANK_PRIMARY,
       mxmf_type_find, "mxmf", MXMF_CAPS, NULL, NULL);
+#ifndef GST_EXT_MIME_TYPES
   TYPE_FIND_REGISTER (plugin, "video/x-fli", GST_RANK_MARGINAL, flx_type_find,
       "flc,fli", FLX_CAPS, NULL, NULL);
+#endif
   TYPE_FIND_REGISTER (plugin, "application/x-id3v2", GST_RANK_PRIMARY + 103,
       id3v2_type_find, "mp3,mp2,mp1,mpga,ogg,flac,tta", ID3_CAPS, NULL, NULL);
   TYPE_FIND_REGISTER (plugin, "application/x-id3v1", GST_RANK_PRIMARY + 101,
       id3v1_type_find, "mp3,mp2,mp1,mpga,ogg,flac,tta", ID3_CAPS, NULL, NULL);
+#ifndef GST_EXT_MIME_TYPES
   TYPE_FIND_REGISTER (plugin, "application/x-apetag", GST_RANK_PRIMARY + 102,
       apetag_type_find, "mp3,ape,mpc,wv", APETAG_CAPS, NULL, NULL);
   TYPE_FIND_REGISTER (plugin, "audio/x-ttafile", GST_RANK_PRIMARY,
@@ -5465,16 +5522,19 @@ plugin_init (GstPlugin * plugin)
   TYPE_FIND_REGISTER (plugin, "audio/x-mod", GST_RANK_SECONDARY, mod_type_find,
       "669,amf,ams,dbm,digi,dmf,dsm,gdm,far,imf,it,j2b,mdl,med,mod,mt2,mtm,"
       "okt,psm,ptm,sam,s3m,stm,stx,ult,xm", MOD_CAPS, NULL, NULL);
+#endif
   TYPE_FIND_REGISTER (plugin, "audio/mpeg", GST_RANK_PRIMARY, mp3_type_find,
       "mp3,mp2,mp1,mpga", MP3_CAPS, NULL, NULL);
   TYPE_FIND_REGISTER (plugin, "audio/x-ac3", GST_RANK_PRIMARY, ac3_type_find,
       "ac3,eac3", AC3_CAPS, NULL, NULL);
   TYPE_FIND_REGISTER (plugin, "audio/x-dts", GST_RANK_SECONDARY, dts_type_find,
       "dts", DTS_CAPS, NULL, NULL);
+#ifndef GST_EXT_MIME_TYPES
   TYPE_FIND_REGISTER (plugin, "audio/x-gsm", GST_RANK_PRIMARY, NULL, "gsm",
       GSM_CAPS, NULL, NULL);
   TYPE_FIND_REGISTER (plugin, "video/mpeg-sys", GST_RANK_PRIMARY,
       mpeg_sys_type_find, "mpe,mpeg,mpg", MPEG_SYS_CAPS, NULL, NULL);
+#endif
   TYPE_FIND_REGISTER (plugin, "video/mpegts", GST_RANK_PRIMARY,
       mpeg_ts_type_find, "ts,mts", MPEGTS_CAPS, NULL, NULL);
   TYPE_FIND_REGISTER (plugin, "application/ogg", GST_RANK_PRIMARY,
@@ -5490,9 +5550,10 @@ plugin_init (GstPlugin * plugin)
       h264_video_type_find, "h264,x264,264", H264_VIDEO_CAPS, NULL, NULL);
   TYPE_FIND_REGISTER (plugin, "video/x-h265", GST_RANK_PRIMARY,
       h265_video_type_find, "h265,x265,265", H265_VIDEO_CAPS, NULL, NULL);
+#ifndef GST_EXT_MIME_TYPES
   TYPE_FIND_REGISTER (plugin, "video/x-nuv", GST_RANK_SECONDARY, nuv_type_find,
       "nuv", NUV_CAPS, NULL, NULL);
-
+#endif
   /* ISO formats */
   TYPE_FIND_REGISTER (plugin, "audio/x-m4a", GST_RANK_PRIMARY, m4a_type_find,
       "m4a", M4A_CAPS, NULL, NULL);
@@ -5500,6 +5561,7 @@ plugin_init (GstPlugin * plugin)
       q3gp_type_find, "3gp", Q3GP_CAPS, NULL, NULL);
   TYPE_FIND_REGISTER (plugin, "video/quicktime", GST_RANK_PRIMARY,
       qt_type_find, "mov,mp4", QT_CAPS, NULL, NULL);
+#ifndef GST_EXT_MIME_TYPES
   TYPE_FIND_REGISTER (plugin, "image/x-quicktime", GST_RANK_SECONDARY,
       qtif_type_find, "qif,qtif,qti", QTIF_CAPS, NULL, NULL);
   TYPE_FIND_REGISTER (plugin, "image/jp2", GST_RANK_PRIMARY,
@@ -5509,13 +5571,14 @@ plugin_init (GstPlugin * plugin)
 
   TYPE_FIND_REGISTER (plugin, "text/html", GST_RANK_SECONDARY, html_type_find,
       "htm,html", HTML_CAPS, NULL, NULL);
+  TYPE_FIND_REGISTER (plugin, "application/x-shockwave-flash",
+      GST_RANK_SECONDARY, swf_type_find, "swf,swfl", SWF_CAPS, NULL, NULL);
+#endif
   TYPE_FIND_REGISTER_START_WITH (plugin, "application/vnd.rn-realmedia",
       GST_RANK_SECONDARY, "ra,ram,rm,rmvb", ".RMF", 4, GST_TYPE_FIND_MAXIMUM);
   TYPE_FIND_REGISTER_START_WITH (plugin, "application/x-pn-realaudio",
       GST_RANK_SECONDARY, "ra,ram,rm,rmvb", ".ra\375", 4,
       GST_TYPE_FIND_MAXIMUM);
-  TYPE_FIND_REGISTER (plugin, "application/x-shockwave-flash",
-      GST_RANK_SECONDARY, swf_type_find, "swf,swfl", SWF_CAPS, NULL, NULL);
   TYPE_FIND_REGISTER (plugin, "application/vnd.ms-sstr+xml",
       GST_RANK_PRIMARY, mss_manifest_type_find, NULL, MSS_MANIFEST_CAPS, NULL,
       NULL);
@@ -5527,18 +5590,23 @@ plugin_init (GstPlugin * plugin)
       "txt", UTF16_CAPS, NULL, NULL);
   TYPE_FIND_REGISTER (plugin, "text/utf-32", GST_RANK_MARGINAL, utf32_type_find,
       "txt", UTF32_CAPS, NULL, NULL);
+#ifndef GST_EXT_MIME_TYPES
   TYPE_FIND_REGISTER (plugin, "text/uri-list", GST_RANK_MARGINAL, uri_type_find,
       "ram", URI_CAPS, NULL, NULL);
+#endif
   TYPE_FIND_REGISTER (plugin, "application/x-hls", GST_RANK_MARGINAL,
       hls_type_find, "m3u8", HLS_CAPS, NULL, NULL);
   TYPE_FIND_REGISTER (plugin, "application/sdp", GST_RANK_SECONDARY,
       sdp_type_find, "sdp", SDP_CAPS, NULL, NULL);
+#ifndef GST_EXT_MIME_TYPES
   TYPE_FIND_REGISTER (plugin, "application/smil", GST_RANK_SECONDARY,
       smil_type_find, "smil", SMIL_CAPS, NULL, NULL);
   TYPE_FIND_REGISTER (plugin, "application/xml", GST_RANK_MARGINAL,
       xml_type_find, "xml", GENERIC_XML_CAPS, NULL, NULL);
+#endif
   TYPE_FIND_REGISTER_RIFF (plugin, "audio/x-wav", GST_RANK_PRIMARY, "wav",
       "WAVE");
+#ifndef GST_EXT_MIME_TYPES
   TYPE_FIND_REGISTER (plugin, "audio/x-aiff", GST_RANK_SECONDARY,
       aiff_type_find, "aiff,aif,aifc", AIFF_CAPS, NULL, NULL);
   TYPE_FIND_REGISTER (plugin, "audio/x-svx", GST_RANK_SECONDARY, svx_type_find,
@@ -5561,6 +5629,7 @@ plugin_init (GstPlugin * plugin)
       shn_type_find, "shn", SHN_CAPS, NULL, NULL);
   TYPE_FIND_REGISTER (plugin, "application/x-ape", GST_RANK_SECONDARY,
       ape_type_find, "ape", APE_CAPS, NULL, NULL);
+#endif
   TYPE_FIND_REGISTER (plugin, "image/jpeg", GST_RANK_PRIMARY + 15,
       jpeg_type_find, "jpg,jpe,jpeg", JPEG_CAPS, NULL, NULL);
   TYPE_FIND_REGISTER_START_WITH (plugin, "image/gif", GST_RANK_PRIMARY, "gif",
@@ -5569,8 +5638,10 @@ plugin_init (GstPlugin * plugin)
       "png", "\211PNG\015\012\032\012", 8, GST_TYPE_FIND_MAXIMUM);
   TYPE_FIND_REGISTER (plugin, "image/bmp", GST_RANK_PRIMARY, bmp_type_find,
       "bmp", BMP_CAPS, NULL, NULL);
+#ifndef GST_EXT_MIME_TYPES
   TYPE_FIND_REGISTER (plugin, "image/tiff", GST_RANK_PRIMARY, tiff_type_find,
       "tif,tiff", TIFF_CAPS, NULL, NULL);
+#endif
   TYPE_FIND_REGISTER_RIFF (plugin, "image/webp", GST_RANK_PRIMARY,
       "webp", "WEBP");
   TYPE_FIND_REGISTER (plugin, "image/x-exr", GST_RANK_PRIMARY, exr_type_find,
@@ -5579,6 +5650,7 @@ plugin_init (GstPlugin * plugin)
       pnm_type_find, "pnm,ppm,pgm,pbm", PNM_CAPS, NULL, NULL);
   TYPE_FIND_REGISTER (plugin, "video/x-matroska", GST_RANK_PRIMARY,
       matroska_type_find, "mkv,mka,mk3d,webm", MATROSKA_CAPS, NULL, NULL);
+#ifndef GST_EXT_MIME_TYPES
   TYPE_FIND_REGISTER (plugin, "application/mxf", GST_RANK_PRIMARY,
       mxf_type_find, "mxf", MXF_CAPS, NULL, NULL);
   TYPE_FIND_REGISTER_START_WITH (plugin, "video/x-mve", GST_RANK_SECONDARY,
@@ -5586,10 +5658,12 @@ plugin_init (GstPlugin * plugin)
       GST_TYPE_FIND_MAXIMUM);
   TYPE_FIND_REGISTER (plugin, "video/x-dv", GST_RANK_SECONDARY, dv_type_find,
       "dv,dif", DV_CAPS, NULL, NULL);
+#endif
   TYPE_FIND_REGISTER_START_WITH (plugin, "audio/x-amr-nb-sh", GST_RANK_PRIMARY,
       "amr", "#!AMR", 5, GST_TYPE_FIND_LIKELY);
   TYPE_FIND_REGISTER_START_WITH (plugin, "audio/x-amr-wb-sh", GST_RANK_PRIMARY,
       "amr", "#!AMR-WB", 7, GST_TYPE_FIND_MAXIMUM);
+#ifndef GST_EXT_MIME_TYPES
   TYPE_FIND_REGISTER (plugin, "audio/iLBC-sh", GST_RANK_PRIMARY, ilbc_type_find,
       "ilbc", ILBC_CAPS, NULL, NULL);
   TYPE_FIND_REGISTER (plugin, "audio/x-sbc", GST_RANK_MARGINAL, sbc_type_find,
@@ -5616,12 +5690,14 @@ plugin_init (GstPlugin * plugin)
       GST_RANK_SECONDARY, "Z", "\037\235", 2, GST_TYPE_FIND_LIKELY);
   TYPE_FIND_REGISTER (plugin, "subtitle/x-kate", GST_RANK_MARGINAL,
       kate_type_find, NULL, NULL, NULL, NULL);
+#endif
   TYPE_FIND_REGISTER (plugin, "audio/x-flac", GST_RANK_PRIMARY, flac_type_find,
       "flac", FLAC_CAPS, NULL, NULL);
   TYPE_FIND_REGISTER (plugin, "audio/x-vorbis", GST_RANK_PRIMARY,
       vorbis_type_find, NULL, VORBIS_CAPS, NULL, NULL);
   TYPE_FIND_REGISTER (plugin, "video/x-theora", GST_RANK_PRIMARY,
       theora_type_find, NULL, THEORA_CAPS, NULL, NULL);
+#ifndef GST_EXT_MIME_TYPES
   TYPE_FIND_REGISTER (plugin, "application/x-ogm-video", GST_RANK_PRIMARY,
       ogmvideo_type_find, NULL, OGMVIDEO_CAPS, NULL, NULL);
   TYPE_FIND_REGISTER (plugin, "application/x-ogm-audio", GST_RANK_PRIMARY,
@@ -5638,8 +5714,10 @@ plugin_init (GstPlugin * plugin)
       NULL, CMML_CAPS, NULL, NULL);
   TYPE_FIND_REGISTER_START_WITH (plugin, "application/x-executable",
       GST_RANK_MARGINAL, NULL, "\177ELF", 4, GST_TYPE_FIND_MAXIMUM);
+#endif
   TYPE_FIND_REGISTER (plugin, "audio/aac", GST_RANK_SECONDARY, aac_type_find,
       "aac,adts,adif,loas", AAC_CAPS, NULL, NULL);
+#ifndef GST_EXT_MIME_TYPES
   TYPE_FIND_REGISTER_START_WITH (plugin, "audio/x-spc", GST_RANK_SECONDARY,
       "spc", "SNES-SPC700 Sound File Data", 27, GST_TYPE_FIND_MAXIMUM);
   TYPE_FIND_REGISTER (plugin, "audio/x-wavpack", GST_RANK_SECONDARY,
@@ -5709,6 +5787,7 @@ plugin_init (GstPlugin * plugin)
 
   TYPE_FIND_REGISTER (plugin, "image/x-degas", GST_RANK_MARGINAL,
       degas_type_find, NULL, NULL, NULL, NULL);
+#endif
   TYPE_FIND_REGISTER (plugin, "application/octet-stream", GST_RANK_MARGINAL,
       dvdiso_type_find, NULL, NULL, NULL, NULL);
 
index 34e3535..8659ce7 100644 (file)
@@ -3,6 +3,7 @@
  * This file:
  * Copyright (C) 2003 Ronald Bultje <rbultje@ronald.bitfreak.net>
  * Copyright (C) 2010 David Schleef <ds@schleef.org>
+ * Copyright (C) 2012, 2013 Samsung Electronics Co., Ltd.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
@@ -18,6 +19,9 @@
  * License along with this library; if not, write to the
  * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
  * Boston, MA 02110-1301, USA.
+ *
+ * Modifications by Samsung Electronics Co., Ltd.
+ * 1. Support samsung extension format
  */
 
 /**
@@ -63,7 +67,9 @@ enum
 };
 
 #define CSP_VIDEO_CAPS GST_VIDEO_CAPS_MAKE (GST_VIDEO_FORMATS_ALL) ";" \
-    GST_VIDEO_CAPS_MAKE_WITH_FEATURES ("ANY", GST_VIDEO_FORMATS_ALL)
+    GST_VIDEO_CAPS_MAKE_WITH_FEATURES ("ANY", GST_VIDEO_FORMATS_ALL) ";" \
+    GST_VIDEO_CAPS_MAKE("{ SUYV , SYVY , S420 , ITLV }") ";" \
+    GST_VIDEO_CAPS_MAKE_WITH_FEATURES ("ANY", "{ SUYV , SYVY , S420 , ITLV }")
 
 static GstStaticPadTemplate gst_video_convert_src_template =
 GST_STATIC_PAD_TEMPLATE ("src",
index 359b347..5fdc2ea 100644 (file)
@@ -1,3 +1,17 @@
+* Wed Jun 24 2014 Andrey Shelest <a.shelest@samsung.com> tizen
+- Added Samsung specific code:
+
+       xvimagesink.c           Add display related properties.
+                               Support samsung extension format to improve performance.
+                               Support video texture overlay of OSP layer.
+       xvimageallocator.c      Add enhancement for additional samsung video formats.
+       xvcontext.c             DRM display functional was implemented.
+       gstvideoconvert.c       Added convertion into samsung extension formats.
+       gsttypefindfunctions.c  Add typefind functions for MIDI audio formats
+       gstplaysink.c           Using fimcconvert plugin for converting video from Sasung specific formats.
+       cameracontrol.c         Interface for camera control.
+       riff-ids.c              Defininition of Microsoft Playready format.
+
 * Tue Jun 18 2013 Anas Nashif <anas.nashif@intel.com> 1.0.7@763b3e2
 - Update to 1.0.7
 
index f778bff..fbf5b52 100644 (file)
@@ -26,6 +26,9 @@ BuildRequires:  pkgconfig(ice)
 BuildRequires:  pkgconfig(sm)
 BuildRequires:  pkgconfig(xext)
 BuildRequires:  pkgconfig(xv)
+BuildRequires:  pkgconfig(xfixes)
+BuildRequires:  pkgconfig(dri2proto)
+BuildRequires:  pkgconfig(libdri2)
 %endif
 %if %{with introspection}
 BuildRequires:  gobject-introspection-devel >= 1.31.1
@@ -45,6 +48,8 @@ BuildRequires:  pkgconfig(theoraenc) >= 1.1
 BuildRequires:  pkgconfig(vorbis) >= 1.0
 BuildRequires:  pkgconfig(vorbisenc) >= 1.0
 BuildRequires:  pkgconfig(zlib)
+BuildRequires:  pkgconfig(libtbm)
+BuildRequires:  pkgconfig(mm-ta)
 Requires:       gstreamer >= 1.0.0
 Supplements:    gstreamer
 
@@ -367,7 +372,13 @@ cp %{SOURCE1001} .
 # Silently ignored compilation of uninstalled gtk-doc scanners without RPM_OPT_FLAGS.
 export V=1
 NOCONFIGURE=1 ./autogen.sh
-export CFLAGS="%{optflags} -fno-strict-aliasing"
+export CFLAGS="%{optflags} -fno-strict-aliasing\
+ %ifarch %{arm}
+ -DGST_EXT_XV_ENHANCEMENT\
+ -DGST_EXT_LINK_FIMCCONVERT\
+ -DGST_EXT_MIME_TYPES
+ %endif
+ "
 %configure\
        --disable-static\
        --enable-experimental\
index 4cf454a..e8e16f5 100644 (file)
@@ -1,11 +1,16 @@
 plugin_LTLIBRARIES = libgstxvimagesink.la
 
 libgstxvimagesink_la_SOURCES =  xvimagesink.c xvimage.c xvimagepool.c xvimageallocator.c xvcontext.c
-libgstxvimagesink_la_CFLAGS = $(GST_PLUGINS_BASE_CFLAGS) $(GST_BASE_CFLAGS) $(GST_CFLAGS) $(X_CFLAGS)
+libgstxvimagesink_la_CFLAGS = $(GST_PLUGINS_BASE_CFLAGS) $(GST_BASE_CFLAGS) $(GST_CFLAGS) $(X_CFLAGS) $(XFIXES_CFLAGS) $(DRI2PROTO_CFLAGS) $(DRI2_CFLAGS) $(TBM_CFLAGS) $(MMTA_CFLAGS)
 libgstxvimagesink_la_LIBADD = \
        $(top_builddir)/gst-libs/gst/video/libgstvideo-$(GST_API_VERSION).la \
        $(GST_BASE_LIBS) \
        $(GST_LIBS) \
+       $(XFIXES_LIBS) \
+       $(DRI2PROTO_LIBS) \
+       $(DRI2_LIBS) \
+        $(TBM_LIBS) \
+        $(MMTA_LIBS) \
        $(X_LIBS) $(XVIDEO_LIBS) $(XSHM_LIBS) $(LIBM)
 libgstxvimagesink_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
 libgstxvimagesink_la_DEPENDENCIES = $(top_builddir)/gst-libs/gst/video/libgstvideo-$(GST_API_VERSION).la
diff --git a/sys/xvimage/xv_types.h b/sys/xvimage/xv_types.h
new file mode 100644 (file)
index 0000000..4afa687
--- /dev/null
@@ -0,0 +1,169 @@
+/**************************************************************************
+
+xserver-xorg-video-exynos
+
+Copyright 2010 - 2011 Samsung Electronics co., Ltd. All Rights Reserved.
+
+Contact: Boram Park <boram1288.park@samsung.com>
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sub license, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice (including the
+next paragraph) shall be included in all copies or substantial portions
+of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
+ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+/*                                                              */
+/* File name : xv_types.h                                       */
+/* Author : Boram Park (boram1288.park@samsung.com)             */
+/* Protocol Version : 1.0.1 (Dec 16th 2009)                       */
+/* This file is for describing Xv APIs' buffer encoding method. */
+/*                                                              */
+
+#ifndef __XV_TYPE_H__
+#define __XV_TYPE_H__
+
+#define XV_DATA_HEADER 0xDEADCD01
+#define XV_DATA_VERSION        0x00010001
+
+/* Return Values */
+#define XV_OK 0
+#define XV_HEADER_ERROR -1
+#define XV_VERSION_MISMATCH -2
+
+/* Video Mode */
+#define DISPLAY_MODE_DEFAULT                                      0
+#define DISPLAY_MODE_PRI_VIDEO_ON_AND_SEC_VIDEO_FULL_SCREEN       1
+#define DISPLAY_MODE_PRI_VIDEO_OFF_AND_SEC_VIDEO_FULL_SCREEN      2
+
+/* Color space range */
+#define CSC_RANGE_NARROW        0
+#define CSC_RANGE_WIDE          1
+
+/* Buffer Type */
+#define XV_BUF_TYPE_DMABUF  0
+#define XV_BUF_TYPE_LEGACY  1
+#define XV_BUF_PLANE_NUM    3
+
+/* 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;
+    unsigned int dmabuf_fd[XV_BUF_PLANE_NUM];
+    unsigned int gem_handle[XV_BUF_PLANE_NUM];
+    void *bo[XV_BUF_PLANE_NUM];
+} XV_DATA, * XV_DATA_PTR;
+
+static void
+#ifdef __GNUC__
+__attribute__ ((unused))
+#endif
+XV_INIT_DATA (XV_DATA_PTR data)
+{
+    data->_header = XV_DATA_HEADER;
+    data->_version = XV_DATA_VERSION;
+}
+
+static int
+#ifdef __GNUC__
+__attribute__ ((unused))
+#endif
+XV_VALIDATE_DATA (XV_DATA_PTR data)
+{
+    if (data->_header != XV_DATA_HEADER)
+        return XV_HEADER_ERROR;
+    if (data->_version != XV_DATA_VERSION)
+        return XV_VERSION_MISMATCH;
+    return XV_OK;
+}
+
+/* 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 dmabuf_fd[SCMN_IMGB_MAX_PLANE];
+    /* buffer share method */
+    int buf_share_method;
+    /* Y plane size in case of ST12 */
+    int y_size;
+    /* UV plane size in case of ST12 */
+    int uv_size;
+    /* Tizen buffer object */
+    void *bo[SCMN_IMGB_MAX_PLANE];
+    /* JPEG data */
+    void *jpeg_data;
+    /* JPEG size */
+    int jpeg_size;
+    /* TZ memory buffer */
+    int tz_enable;
+} SCMN_IMGB;
+
+#endif
+
index 146e4a5..8d171f0 100644 (file)
@@ -37,6 +37,26 @@ GST_DEBUG_CATEGORY_EXTERN (gst_debug_xvcontext);
 GST_DEBUG_CATEGORY_EXTERN (GST_CAT_PERFORMANCE);
 #define GST_CAT_DEFAULT gst_debug_xvcontext
 
+#ifdef GST_EXT_XV_ENHANCEMENT
+#define _BUFFER_WAIT_TIMEOUT            2000000
+#define _CHECK_DISPLAYED_BUFFER_COUNT   30
+
+/* headers for drm */
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <xf86drm.h>
+#include <xf86drmMode.h>
+#include <X11/Xmd.h>
+#include <dri2/dri2.h>
+#include <tbm_bufmgr.h>
+
+static XImage *make_transparent_image(Display *d, Window win, int w, int h);
+static unsigned int drm_convert_dmabuf_gemname(GstXvContext *context, unsigned int dmabuf_fd, unsigned int *gem_handle);
+static void drm_close_gem(GstXvContext *context, unsigned int *gem_handle);
+#endif /* GST_EXT_XV_ENHANCEMENT */
+
 void
 gst_xvcontext_config_clear (GstXvContextConfig * config)
 {
@@ -442,8 +462,18 @@ gst_xvimage_handle_xerror (Display * display, XErrorEvent * xevent)
 {
   char error_msg[1024];
 
+#ifdef GST_EXT_XV_ENHANCEMENT
+  if (xevent) {
+    XGetErrorText (display, xevent->error_code, error_msg, 1024);
+    error_msg[1023] = '\0';
+    GST_DEBUG ("context triggered an XError. error: %s", error_msg);
+  } else {
+    GST_ERROR("CAUTION:xevent is NULL");
+  }
+#else /* GST_EXT_XV_ENHANCEMENT */
   XGetErrorText (display, xevent->error_code, error_msg, 1024);
   GST_DEBUG ("xvimage triggered an XError. error: %s", error_msg);
+#endif /* GST_EXT_XV_ENHANCEMENT */
   error_caught = TRUE;
   return 0;
 }
@@ -611,11 +641,76 @@ gst_xvcontext_free (GstXvContext * context)
   if (context->disp)
     XCloseDisplay (context->disp);
 
+#ifdef GST_EXT_XV_ENHANCEMENT
+  if (context->display_buffer_lock) {
+    g_mutex_free (context->display_buffer_lock);
+    context->display_buffer_lock = NULL;
+  }
+  if (context->display_buffer_cond) {
+    g_cond_free (context->display_buffer_cond);
+    context->display_buffer_cond = NULL;
+  }
+#endif /* GST_EXT_XV_ENHANCEMENT */
+
   g_mutex_clear (&context->lock);
 
   g_slice_free1 (sizeof (GstXvContext), context);
 }
 
+#ifdef GST_EXT_XV_ENHANCEMENT
+gboolean gst_xvcontext_set_display_mode(GstXvContext *context, int set_mode)
+{
+  int ret = 0;
+  static gboolean is_exist = FALSE;
+  static XvPortID current_port_id = -1;
+  Atom atom_output = None;
+
+  if (context == NULL) {
+    GST_WARNING("context is NULL");
+    return FALSE;
+  }
+
+  /* check once per one xv_port_id */
+  if (current_port_id != context->xv_port_id) {
+    /* check whether _USER_WM_PORT_ATTRIBUTE_OUTPUT attribute is existed */
+    int i = 0;
+    int count = 0;
+    XvAttribute *const attr = XvQueryPortAttributes(context->disp,
+                                                    context->xv_port_id, &count);
+    if (attr) {
+      current_port_id = context->xv_port_id;
+      for (i = 0 ; i < count ; i++) {
+        if (!strcmp(attr[i].name, "_USER_WM_PORT_ATTRIBUTE_OUTPUT")) {
+          is_exist = TRUE;
+          GST_INFO("_USER_WM_PORT_ATTRIBUTE_OUTPUT[index %d] found", i);
+          break;
+        }
+      }
+      XFree(attr);
+    } else {
+      GST_WARNING("XvQueryPortAttributes disp:%d, port_id:%d failed",
+                  context->disp, context->xv_port_id);
+    }
+  }
+
+  if (is_exist) {
+    GST_INFO("set display mode %d", set_mode);
+    atom_output = XInternAtom(context->disp,
+                              "_USER_WM_PORT_ATTRIBUTE_OUTPUT", False);
+    ret = XvSetPortAttribute(context->disp, context->xv_port_id,
+                             atom_output, set_mode);
+    if (ret == Success) {
+      return TRUE;
+    } else {
+      GST_WARNING("display mode[%d] set failed.", set_mode);
+    }
+  } else {
+    GST_WARNING("_USER_WM_PORT_ATTRIBUTE_OUTPUT is not existed");
+  }
+
+  return FALSE;
+}
+#endif /* GST_EXT_XV_ENHANCEMENT */
 
 /* 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
@@ -707,12 +802,12 @@ gst_xvcontext_new (GstXvContextConfig * config, GError ** error)
   if (XShmQueryExtension (context->disp) &&
       gst_xvcontext_check_xshm_calls (context)) {
     context->use_xshm = TRUE;
-    GST_DEBUG ("xvimagesink is using XShm extension");
+    GST_DEBUG ("context is using XShm extension");
   } else
 #endif /* HAVE_XSHM */
   {
     context->use_xshm = FALSE;
-    GST_DEBUG ("xvimagesink is not using XShm extension");
+    GST_DEBUG ("context is not using XShm extension");
   }
 
   xv_attr = XvQueryPortAttributes (context->disp, context->xv_port_id, &N_attr);
@@ -768,7 +863,28 @@ gst_xvcontext_new (GstXvContextConfig * config, GError ** error)
 
   if (xv_attr)
     XFree (xv_attr);
+#ifdef GST_EXT_XV_ENHANCEMENT
+  context->xim_transparenter = NULL;
+  gst_xvcontext_set_display_mode(context, config->display_mode);
+  context->drm_fd = -1;
+
+  for (i = 0 ; i < DISPLAYING_BUFFERS_MAX_NUM ; i++) {
+    context->displaying_buffers[i].buffer = NULL;
+    for (j = 0 ; j < XV_BUF_PLANE_NUM ; j++) {
+      context->displaying_buffers[i].gem_name[j] = 0;
+      context->displaying_buffers[i].gem_handle[j] = 0;
+      context->displaying_buffers[i].dmabuf_fd[j] = 0;
+      context->displaying_buffers[i].ref_count = 0;
+    }
+  }
+
+  context->display_buffer_lock = g_mutex_new ();
+  context->display_buffer_cond = g_cond_new ();
+
+  context->displayed_buffer_count = 0;
+  context->displaying_buffer_count = 0;
 
+#endif /* GST_EXT_XV_ENHANCEMENT */
   return context;
 
   /* ERRORS */
@@ -865,7 +981,7 @@ gst_xvcontext_update_colorbalance (GstXvContext * context,
 }
 
 /* This function tries to get a format matching with a given caps in the
-   supported list of formats we generated in gst_xvimagesink_get_xv_support */
+   supported list of formats we generated in gst_context_get_xv_support */
 gint
 gst_xvcontext_get_format_from_info (GstXvContext * context, GstVideoInfo * info)
 {
@@ -910,12 +1026,45 @@ gst_xvcontext_set_colorimetry (GstXvContext * context,
   g_mutex_unlock (&context->lock);
 }
 
+#ifdef GST_EXT_XV_ENHANCEMENT
+static XImage *make_transparent_image(Display *d, Window win, int w, int h)
+{
+  XImage *xim;
+
+  /* create a normal ximage */
+  xim = XCreateImage(d, DefaultVisualOfScreen(DefaultScreenOfDisplay(d)),  24, ZPixmap, 0, NULL, w, h, 32, 0);
+
+  GST_INFO("ximage %p", xim);
+
+  /* allocate data for it */
+  if (xim) {
+    xim->data = (char *)malloc(xim->bytes_per_line * xim->height);
+    if (xim->data) {
+      memset(xim->data, 0x00, xim->bytes_per_line * xim->height);
+      return xim;
+    } else {
+      GST_ERROR("failed to alloc data - size %d", xim->bytes_per_line * xim->height);
+    }
+
+    XDestroyImage(xim);
+  }
+
+  GST_ERROR("failed to create Ximage");
+
+  return NULL;
+}
+#endif /* GST_EXT_XV_ENHANCEMENT */
+
 GstXWindow *
 gst_xvcontext_create_xwindow (GstXvContext * context, gint width, gint height)
 {
   GstXWindow *window;
   Atom wm_delete;
   Atom hints_atom = None;
+#ifdef GST_EXT_XV_ENHANCEMENT
+  XSetWindowAttributes win_attr;
+  XWindowAttributes root_attr;
+#endif /* GST_EXT_XV_ENHANCEMENT */
 
   g_return_val_if_fail (GST_IS_XVCONTEXT (context), NULL);
 
@@ -929,12 +1078,45 @@ gst_xvcontext_create_xwindow (GstXvContext * context, gint width, gint height)
 
   window->width = width;
   window->height = height;
+#ifdef GST_EXT_XV_ENHANCEMENT
+  XGetWindowAttributes(context->disp, context->root, &root_attr);
+
+  if (window->width > root_attr.width) {
+    GST_INFO_OBJECT(context, "Width[%d] is bigger than Max width. Set Max[%d].",
+                                 window->width, root_attr.width);
+    window->render_rect.w = window->width = root_attr.width;
+  }
+  if (window->height > root_attr.height) {
+    GST_INFO_OBJECT(context, "Height[%d] is bigger than Max Height. Set Max[%d].",
+                                 window->height, root_attr.height);
+    window->render_rect.h = window->height = root_attr.height;
+  }
+  window->internal = TRUE;
+
+  g_mutex_lock (&context->lock);
+
+  GST_DEBUG_OBJECT( context, "window create [%dx%d]", window->width, window->height );
+
+  window->win = XCreateSimpleWindow(context->disp,
+                                     context->root,
+                                     0, 0, window->width, window->height,
+                                     0, 0, 0);
+
+  context->xim_transparenter = make_transparent_image(context->disp,
+                                                          context->root,
+                                                          window->width, window->height);
+
+  /* Make window manager not to change window size as Full screen */
+  win_attr.override_redirect = True;
+  XChangeWindowAttributes(context->disp, window->win, CWOverrideRedirect, &win_attr);
+#else /* GST_EXT_XV_ENHANCEMENT */
   window->internal = TRUE;
 
   g_mutex_lock (&context->lock);
 
   window->win = XCreateSimpleWindow (context->disp,
       context->root, 0, 0, width, height, 0, 0, context->black);
+#endif /* GST_EXT_XV_ENHANCEMENT */
 
   /* We have to do that to prevent X from redrawing the background on
    * ConfigureNotify. This takes away flickering of video when resizing. */
@@ -1018,8 +1200,15 @@ gst_xwindow_destroy (GstXWindow * window)
   g_mutex_lock (&context->lock);
 
   /* If we did not create that window we just free the GC and let it live */
-  if (window->internal)
+  if (window->internal) {
     XDestroyWindow (context->disp, window->win);
+#ifdef GST_EXT_XV_ENHANCEMENT
+    if (context->xim_transparenter) {
+      XDestroyImage(context->xim_transparenter);
+      context->xim_transparenter = NULL;
+    }
+#endif /* GST_EXT_XV_ENHANCEMENT */
+  }
   else
     XSelectInput (context->disp, window->win, 0);
 
@@ -1083,7 +1272,19 @@ gst_xwindow_set_title (GstXWindow * window, const gchar * title)
 void
 gst_xwindow_update_geometry (GstXWindow * window)
 {
+#ifdef GST_EXT_XV_ENHANCEMENT
+  Window root_window, child_window;
+  XWindowAttributes root_attr;
+
+  int cur_win_x = 0;
+  int cur_win_y = 0;
+  unsigned int cur_win_width = 0;
+  unsigned int cur_win_height = 0;
+  unsigned int cur_win_border_width = 0;
+  unsigned int cur_win_depth = 0;
+#else /* GST_EXT_XV_ENHANCEMENT */
   XWindowAttributes attr;
+#endif /* GST_EXT_XV_ENHANCEMENT */
   GstXvContext *context;
 
   g_return_if_fail (window != NULL);
@@ -1092,6 +1293,39 @@ gst_xwindow_update_geometry (GstXWindow * window)
 
   /* Update the window geometry */
   g_mutex_lock (&context->lock);
+#ifdef GST_EXT_XV_ENHANCEMENT
+  /* Get root window and size of current window */
+  XGetGeometry( context->disp, window->win, &root_window,
+    &cur_win_x, &cur_win_y, /* relative x, y */
+    &cur_win_width, &cur_win_height,
+    &cur_win_border_width, &cur_win_depth );
+
+  window->width = cur_win_width;
+  window->height = cur_win_height;
+
+  /* Get absolute coordinates of current window */
+  XTranslateCoordinates( context->disp,
+    window->win,
+    root_window,
+    0, 0,
+    &cur_win_x, &cur_win_y, // relative x, y to root window == absolute x, y
+    &child_window );
+
+  /* Get size of root window == size of screen */
+  XGetWindowAttributes(context->disp, root_window, &root_attr);
+
+  if (!window->have_render_rect) {
+      window->render_rect.x = window->render_rect.y = 0;
+      window->render_rect.w = cur_win_width;
+      window->render_rect.h = cur_win_height;
+  }
+
+  GST_LOG_OBJECT(window, "screen size %dx%d, current window geometry %dx%d, render_rect %d,%d,%dx%d",
+          root_attr.width, root_attr.height,
+    window->width, window->height,
+    window->render_rect.x, window->render_rect.y,
+    window->render_rect.w, window->render_rect.h);
+#else /* GST_EXT_XV_ENHANCEMENT */
   XGetWindowAttributes (context->disp, window->win, &attr);
 
   window->width = attr.width;
@@ -1102,6 +1336,7 @@ gst_xwindow_update_geometry (GstXWindow * window)
     window->render_rect.w = attr.width;
     window->render_rect.h = attr.height;
   }
+#endif /* GST_EXT_XV_ENHANCEMENT */
 
   g_mutex_unlock (&context->lock);
 }
@@ -1117,6 +1352,9 @@ gst_xwindow_clear (GstXWindow * window)
   context = window->context;
 
   g_mutex_lock (&context->lock);
+#ifdef GST_EXT_XV_ENHANCEMENT
+  GST_WARNING_OBJECT(context, "CALL XvStopVideo");
+#endif /* GST_EXT_XV_ENHANCEMENT */
 
   XvStopVideo (context->disp, context->xv_port_id, window->win);
 
@@ -1145,3 +1383,465 @@ gst_xwindow_set_render_rectangle (GstXWindow * window,
     window->have_render_rect = FALSE;
   }
 }
+
+#ifdef GST_EXT_XV_ENHANCEMENT
+void gst_xvcontext_drm_init(GstXvContext *context)
+{
+   Display *dpy;
+   int eventBase = 0;
+   int errorBase = 0;
+   int dri2Major = 0;
+   int dri2Minor = 0;
+   char *driverName = NULL;
+   char *deviceName = NULL;
+   struct drm_auth auth_arg = {0};
+
+   context->drm_fd = -1;
+
+   dpy = XOpenDisplay(0);
+   if (!dpy) {
+       GST_ERROR("XOpenDisplay failed errno:%d", errno);
+       return;
+   }
+
+   GST_INFO("START");
+
+   /* DRI2 */
+   if (!DRI2QueryExtension(dpy, &eventBase, &errorBase)) {
+       GST_ERROR("DRI2QueryExtension !!");
+       goto DRM_INIT_ERROR;
+   }
+
+   if (!DRI2QueryVersion(dpy, &dri2Major, &dri2Minor)) {
+       GST_ERROR("DRI2QueryVersion !!");
+       goto DRM_INIT_ERROR;
+   }
+
+   if (!DRI2Connect(dpy, RootWindow(dpy, DefaultScreen(dpy)), &driverName, &deviceName)) {
+       GST_ERROR("DRI2Connect !!");
+       goto DRM_INIT_ERROR;
+   }
+
+   if (!driverName || !deviceName) {
+       GST_ERROR("driverName or deviceName is not valid");
+       goto DRM_INIT_ERROR;
+   }
+
+   GST_INFO("Open drm device : %s", deviceName);
+
+   /* get the drm_fd though opening the deviceName */
+   context->drm_fd = open(deviceName, O_RDWR);
+   if (context->drm_fd < 0) {
+       GST_ERROR("cannot open drm device (%s)", deviceName);
+       goto DRM_INIT_ERROR;
+   }
+
+   /* get magic from drm to authentication */
+   if (ioctl(context->drm_fd, DRM_IOCTL_GET_MAGIC, &auth_arg)) {
+       GST_ERROR("cannot get drm auth magic");
+       goto DRM_INIT_ERROR;
+   }
+
+   if (!DRI2Authenticate(dpy, RootWindow(dpy, DefaultScreen(dpy)), auth_arg.magic)) {
+       GST_ERROR("cannot get drm authentication from X");
+       goto DRM_INIT_ERROR;
+   }
+
+   XCloseDisplay(dpy);
+   free(driverName);
+   free(deviceName);
+
+   GST_INFO("DONE");
+
+   return;
+
+DRM_INIT_ERROR:
+   if (context->drm_fd >= 0) {
+       close(context->drm_fd);
+       context->drm_fd = -1;
+   }
+   if (dpy) {
+       XCloseDisplay(dpy);
+   }
+   if (driverName) {
+       free(driverName);
+   }
+   if (deviceName) {
+       free(deviceName);
+   }
+
+   return;
+}
+
+void gst_xvcontext_drm_fini(GstXvContext *context)
+{
+   GST_INFO("START");
+
+   if (context->drm_fd >= 0) {
+       int i;
+       int j;
+       gboolean is_timeout = FALSE;
+
+       /* close remained gem handle */
+       g_mutex_lock(context->display_buffer_lock);
+       for (i = 0 ; i < DISPLAYING_BUFFERS_MAX_NUM ; i++) {
+               if (context->displaying_buffers[i].buffer) {
+                       GTimeVal abstimeout;
+
+                       GST_WARNING("remained buffer %p, name %u %u %u, handle %u %u %u",
+                                   context->displaying_buffers[i].buffer,
+                                   context->displaying_buffers[i].gem_name[0],
+                                   context->displaying_buffers[i].gem_name[1],
+                                   context->displaying_buffers[i].gem_name[2],
+                                   context->displaying_buffers[i].gem_handle[0],
+                                   context->displaying_buffers[i].gem_handle[1],
+                                   context->displaying_buffers[i].gem_handle[2]);
+
+                       g_get_current_time(&abstimeout);
+                       g_time_val_add(&abstimeout, _BUFFER_WAIT_TIMEOUT);
+
+                       if (is_timeout ||
+                           !g_cond_timed_wait(context->display_buffer_cond,
+                                              context->display_buffer_lock,
+                                              &abstimeout)) {
+                               GST_ERROR("Buffer wait timeout[%d usec] or is_timeout[%d]. Force Unref buffer",
+                                         _BUFFER_WAIT_TIMEOUT, is_timeout);
+
+                               /* set flag not to wait next time */
+                               is_timeout = TRUE;
+
+                               for (j = 0 ; j < XV_BUF_PLANE_NUM ; j++) {
+                                       if (context->displaying_buffers[i].gem_handle[j] > 0) {
+                                               drm_close_gem(context, &(context->displaying_buffers[i].gem_handle[j]));
+                                       }
+                                       context->displaying_buffers[i].gem_name[j] = 0;
+                                       context->displaying_buffers[i].dmabuf_fd[j] = 0;
+                                       context->displaying_buffers[i].bo[j] = NULL;
+                               }
+
+                               gst_buffer_unref(context->displaying_buffers[i].buffer);
+                               context->displaying_buffers[i].buffer = NULL;
+                       } else {
+                               GST_WARNING("Signal received. check again...");
+                       }
+
+                       /* init index and check again from first */
+                       i = -1;
+               }
+       }
+       g_mutex_unlock(context->display_buffer_lock);
+       GST_INFO("close drm_fd %d", context->drm_fd);
+       close(context->drm_fd);
+       context->drm_fd = -1;
+   } else {
+       GST_INFO("DRM device is NOT opened");
+   }
+
+   /* init displaying_buffer_count */
+   context->displaying_buffer_count = 0;
+
+   GST_INFO("DONE");
+}
+
+static unsigned int drm_convert_dmabuf_gemname(GstXvContext *context, unsigned int dmabuf_fd, unsigned int *gem_handle)
+{
+   int ret = 0;
+
+   struct drm_prime_handle prime_arg = {0,};
+   struct drm_gem_flink flink_arg = {0,};
+
+   if (!context || !gem_handle) {
+       GST_ERROR("handle[%p,%p] is NULL", context, gem_handle);
+       return 0;
+   }
+
+   if (context->drm_fd <= 0) {
+       GST_ERROR("DRM is not opened");
+       return 0;
+   }
+
+   if (dmabuf_fd <= 0) {
+       GST_LOG("Ignore wrong dmabuf fd [%u]", dmabuf_fd);
+       return 0;
+   }
+
+   prime_arg.fd = dmabuf_fd;
+   ret = ioctl(context->drm_fd, DRM_IOCTL_PRIME_FD_TO_HANDLE, &prime_arg);
+   if (ret) {
+       GST_ERROR("DRM_IOCTL_PRIME_FD_TO_HANDLE failed. ret %d, dmabuf fd : %u", ret, dmabuf_fd);
+       return 0;
+   }
+
+   *gem_handle = prime_arg.handle;
+   flink_arg.handle = prime_arg.handle;
+   ret = ioctl(context->drm_fd, DRM_IOCTL_GEM_FLINK, &flink_arg);
+   if (ret) {
+       GST_ERROR("DRM_IOCTL_GEM_FLINK failed. ret %d, gem_handle %u, gem_name %u", ret, *gem_handle, flink_arg.name);
+       return 0;
+   }
+
+   return flink_arg.name;
+}
+
+static void drm_close_gem(GstXvContext *context, unsigned int *gem_handle)
+{
+       struct drm_gem_close close_arg = {0,};
+
+       if (context->drm_fd < 0 || !gem_handle) {
+               GST_ERROR("DRM is not opened");
+               return;
+       }
+
+       if (*gem_handle <= 0) {
+               GST_DEBUG("invalid gem handle %u", *gem_handle);
+               return;
+       }
+
+       GST_LOG("Call DRM_IOCTL_GEM_CLOSE - handle %u", *gem_handle);
+
+       close_arg.handle = *gem_handle;
+       if (ioctl(context->drm_fd, DRM_IOCTL_GEM_CLOSE, &close_arg)) {
+               GST_ERROR("cannot close drm gem handle %u", gem_handle);
+               return;
+       }
+
+       *gem_handle = 0;
+
+       return;
+}
+
+void gst_xvcontext_add_displaying_buffer(GstXvContext *context, XV_DATA_PTR img_data, GstBuffer *buffer)
+{
+    int i = 0;
+    int j = 0;
+
+    if (!context || !img_data) {
+        GST_ERROR("handle is NULL %p, %p", context, img_data);
+        return;
+    }
+
+    /* lock display buffer mutex */
+    g_mutex_lock(context->display_buffer_lock);
+
+    /* increase displaying buffer count */
+    context->displaying_buffer_count++;
+
+    /* check duplicated */
+    for (i = 0 ; i < DISPLAYING_BUFFERS_MAX_NUM ; i++) {
+        if (context->displaying_buffers[i].gem_name[0] > 0) {
+            if ((img_data->dmabuf_fd[0] > 0 &&
+                 context->displaying_buffers[i].dmabuf_fd[0] == img_data->dmabuf_fd[0] &&
+                 context->displaying_buffers[i].dmabuf_fd[1] == img_data->dmabuf_fd[1] &&
+                 context->displaying_buffers[i].dmabuf_fd[2] == img_data->dmabuf_fd[2]) ||
+                (img_data->bo[0] &&
+                 context->displaying_buffers[i].bo[0] == img_data->bo[0] &&
+                 context->displaying_buffers[i].bo[1] == img_data->bo[1] &&
+                 context->displaying_buffers[i].bo[2] == img_data->bo[2])) {
+                /* increase ref count */
+                context->displaying_buffers[i].ref_count++;
+
+                /* set buffer info */
+                img_data->YBuf = context->displaying_buffers[i].gem_name[0];
+                img_data->CbBuf = context->displaying_buffers[i].gem_name[1];
+                img_data->CrBuf = context->displaying_buffers[i].gem_name[2];
+
+                if (img_data->dmabuf_fd[0] > 0) {
+                    GST_WARNING("already converted fd [%u %u %u] name [%u %u %u]",
+                                img_data->dmabuf_fd[0], img_data->dmabuf_fd[1], img_data->dmabuf_fd[2],
+                                img_data->YBuf, img_data->CbBuf, img_data->CrBuf);
+                } else {
+                    GST_WARNING("already exported bo [%p %p %p] gem name [%u %u %u]",
+                                img_data->bo[0], img_data->bo[1], img_data->bo[2],
+                                img_data->YBuf, img_data->CbBuf, img_data->CrBuf);
+                }
+
+                /* unlock display buffer mutex */
+                g_mutex_unlock(context->display_buffer_lock);
+                return;
+            }
+        }
+    }
+
+    /* store buffer temporarily */
+    for (i = 0 ; i < DISPLAYING_BUFFERS_MAX_NUM ; i++) {
+        if (context->displaying_buffers[i].gem_name[0] == 0) {
+            if (buffer) {
+                /* increase ref count of buffer */
+                gst_buffer_ref(buffer);
+                context->displaying_buffers[i].buffer = buffer;
+            }
+
+            if (img_data->dmabuf_fd[0] > 0) {
+                /* convert fd to name */
+                img_data->YBuf = drm_convert_dmabuf_gemname(context, img_data->dmabuf_fd[0], &img_data->gem_handle[0]);
+                img_data->CbBuf = drm_convert_dmabuf_gemname(context, img_data->dmabuf_fd[1], &img_data->gem_handle[1]);
+                img_data->CrBuf = drm_convert_dmabuf_gemname(context, img_data->dmabuf_fd[2], &img_data->gem_handle[2]);
+            } else {
+                /* export bo */
+                if (img_data->bo[0]) {
+                    img_data->YBuf = tbm_bo_export(img_data->bo[0]);
+                }
+                if (img_data->bo[1]) {
+                    img_data->CbBuf = tbm_bo_export(img_data->bo[1]);
+                }
+                if (img_data->bo[2]) {
+                    img_data->CrBuf = tbm_bo_export(img_data->bo[2]);
+                }
+            }
+
+            for (j = 0 ; j < XV_BUF_PLANE_NUM ; j++) {
+                context->displaying_buffers[i].dmabuf_fd[j] = img_data->dmabuf_fd[j];
+                context->displaying_buffers[i].gem_handle[j] = img_data->gem_handle[j];
+                context->displaying_buffers[i].bo[j] = img_data->bo[j];
+            }
+
+            /* set buffer info */
+            context->displaying_buffers[i].gem_name[0] = img_data->YBuf;
+            context->displaying_buffers[i].gem_name[1] = img_data->CbBuf;
+            context->displaying_buffers[i].gem_name[2] = img_data->CrBuf;
+
+            /* set ref count */
+            context->displaying_buffers[i].ref_count = 1;
+
+            if (context->displayed_buffer_count < _CHECK_DISPLAYED_BUFFER_COUNT) {
+                GST_WARNING_OBJECT(context, "cnt %d - add idx %d, buf %p, fd [%u %u %u], handle [%u %u %u], name [%u %u %u]",
+                                                context->displayed_buffer_count,
+                                                i, context->displaying_buffers[i].buffer,
+                                                context->displaying_buffers[i].dmabuf_fd[0],
+                                                context->displaying_buffers[i].dmabuf_fd[1],
+                                                context->displaying_buffers[i].dmabuf_fd[2],
+                                                context->displaying_buffers[i].gem_handle[0],
+                                                context->displaying_buffers[i].gem_handle[1],
+                                                context->displaying_buffers[i].gem_handle[2],
+                                                context->displaying_buffers[i].gem_name[0],
+                                                context->displaying_buffers[i].gem_name[1],
+                                                context->displaying_buffers[i].gem_name[2]);
+            } else {
+                GST_DEBUG_OBJECT(context, "add idx %d, buf %p, fd [%u %u %u], handle [%u %u %u], name [%u %u %u]",
+                                              i, context->displaying_buffers[i].buffer,
+                                              context->displaying_buffers[i].dmabuf_fd[0],
+                                              context->displaying_buffers[i].dmabuf_fd[1],
+                                              context->displaying_buffers[i].dmabuf_fd[2],
+                                              context->displaying_buffers[i].gem_handle[0],
+                                              context->displaying_buffers[i].gem_handle[1],
+                                              context->displaying_buffers[i].gem_handle[2],
+                                              context->displaying_buffers[i].gem_name[0],
+                                              context->displaying_buffers[i].gem_name[1],
+                                              context->displaying_buffers[i].gem_name[2]);
+            }
+
+            /* unlock display buffer mutex */
+            g_mutex_unlock(context->display_buffer_lock);
+
+            /* get current time */
+            gettimeofday(&context->request_time[i], NULL);
+            return;
+        }
+    }
+
+    /* decrease displaying buffer count */
+    context->displaying_buffer_count--;
+
+    /* unlock display buffer mutex */
+    g_mutex_unlock(context->display_buffer_lock);
+
+    GST_ERROR("should not be reached here. buffer slot is FULL...");
+}
+
+void gst_xvcontext_remove_displaying_buffer(GstXvContext *context, unsigned int *gem_name)
+{
+    int i = 0;
+    int j = 0;
+
+    if (!context || !gem_name) {
+        GST_ERROR("handle is NULL %p, %p", context, gem_name);
+        return;
+    }
+
+    /* lock display buffer mutex */
+    g_mutex_lock(context->display_buffer_lock);
+
+    if (context->displaying_buffer_count == 0) {
+        GST_WARNING("there is no displaying buffer");
+        /* unlock display buffer mutex */
+        g_mutex_unlock(context->display_buffer_lock);
+        return;
+    }
+
+    GST_DEBUG("gem name [%u %u %u], displaying buffer count %d",
+              gem_name[0], gem_name[1], gem_name[2],
+              context->displaying_buffer_count);
+
+    for (i = 0 ; i < DISPLAYING_BUFFERS_MAX_NUM ; i++) {
+        if (context->displaying_buffers[i].gem_name[0] == gem_name[0] &&
+            context->displaying_buffers[i].gem_name[1] == gem_name[1] &&
+            context->displaying_buffers[i].gem_name[2] == gem_name[2]) {
+            struct timeval current_time;
+
+            /* get current time to calculate displaying time */
+            gettimeofday(&current_time, NULL);
+
+            GST_DEBUG_OBJECT(context, "buffer return time %8d us",
+                                          (current_time.tv_sec - context->request_time[i].tv_sec)*1000000 + \
+                                          (current_time.tv_usec - context->request_time[i].tv_usec));
+
+            if (context->displayed_buffer_count < _CHECK_DISPLAYED_BUFFER_COUNT) {
+                context->displayed_buffer_count++;
+                GST_WARNING_OBJECT(context, "cnt %d - remove idx %d, buf %p, handle [%u %u %u], name [%u %u %u]",
+                                                context->displayed_buffer_count,
+                                                i, context->displaying_buffers[i].buffer,
+                                                context->displaying_buffers[i].gem_handle[0],
+                                                context->displaying_buffers[i].gem_handle[1],
+                                                context->displaying_buffers[i].gem_handle[2],
+                                                context->displaying_buffers[i].gem_name[0],
+                                                context->displaying_buffers[i].gem_name[1],
+                                                context->displaying_buffers[i].gem_name[2]);
+            } else {
+                GST_DEBUG_OBJECT(context, "remove idx %d, buf %p, handle [%u %u %u], name [%u %u %u]",
+                                              i, context->displaying_buffers[i].buffer,
+                                              context->displaying_buffers[i].gem_handle[0],
+                                              context->displaying_buffers[i].gem_handle[1],
+                                              context->displaying_buffers[i].gem_handle[2],
+                                              context->displaying_buffers[i].gem_name[0],
+                                              context->displaying_buffers[i].gem_name[1],
+                                              context->displaying_buffers[i].gem_name[2]);
+            }
+
+            /* decrease displaying buffer count */
+            context->displaying_buffer_count--;
+
+            /* decrease ref count */
+            context->displaying_buffers[i].ref_count--;
+
+            if (context->displaying_buffers[i].ref_count > 0) {
+                GST_WARNING("ref count not zero[%d], skip close gem handle",
+                            context->displaying_buffers[i].ref_count);
+                break;
+            }
+
+            for (j = 0 ; j < XV_BUF_PLANE_NUM ; j++) {
+                if (context->displaying_buffers[i].gem_handle[j] > 0) {
+                    drm_close_gem(context, &(context->displaying_buffers[i].gem_handle[j]));
+                }
+                context->displaying_buffers[i].gem_name[j] = 0;
+                context->displaying_buffers[i].dmabuf_fd[j] = 0;
+                context->displaying_buffers[i].bo[j] = NULL;
+            }
+
+            if (context->displaying_buffers[i].buffer) {
+                gst_buffer_unref(context->displaying_buffers[i].buffer);
+                context->displaying_buffers[i].buffer = NULL;
+            } else {
+                GST_WARNING("no buffer to unref");
+            }
+            break;
+        }
+    }
+
+    /* send signal to wait display_buffer_cond */
+    g_cond_signal(context->display_buffer_cond);
+
+    /* unlock display buffer mutex */
+    g_mutex_unlock(context->display_buffer_lock);
+}
+#endif /* GST_EXT_XV_ENHANCEMENT */
index 1bd0d97..7f49ef9 100644 (file)
@@ -69,6 +69,11 @@ struct _GstXvContextConfig
   gint hue;
   gint saturation;
   gboolean cb_changed;
+
+#ifdef GST_EXT_XV_ENHANCEMENT
+  /* display mode */
+  guint display_mode;
+#endif /* GST_EXT_XV_ENHANCEMENT */
 };
 
 /**
@@ -90,6 +95,21 @@ struct _GstXvImageFormat
 #define GST_XVCONTEXT_CAST(obj) ((GstXvContext *)obj)
 #define GST_XVCONTEXT(obj)      (GST_XVCONTEXT_CAST(obj))
 
+#ifdef GST_EXT_XV_ENHANCEMENT
+#define DISPLAYING_BUFFERS_MAX_NUM 10
+
+#include "xv_types.h"
+
+typedef struct {
+       GstBuffer *buffer;
+       unsigned int dmabuf_fd[XV_BUF_PLANE_NUM];
+       unsigned int gem_name[XV_BUF_PLANE_NUM];
+       unsigned int gem_handle[XV_BUF_PLANE_NUM];
+       void *bo[XV_BUF_PLANE_NUM];
+       unsigned int ref_count;
+} GstXvImageDisplayingBuffer;
+#endif /* GST_EXT_XV_ENHANCEMENT */
+
 /*
  * GstXvContext:
  * @disp: the X11 Display of this context
@@ -168,6 +188,22 @@ struct _GstXvContext
   gint last_format;
   gint last_width;
   gint last_height;
+#ifdef GST_EXT_XV_ENHANCEMENT
+  XImage* xim_transparenter;
+  gint drm_fd;
+
+  /* for sync displaying buffers */
+  GstXvImageDisplayingBuffer displaying_buffers[DISPLAYING_BUFFERS_MAX_NUM];
+  GMutex *display_buffer_lock;
+  GCond *display_buffer_cond;
+
+  /* buffer count check */
+  guint displayed_buffer_count;
+  guint displaying_buffer_count;
+
+  /* display request time */
+  struct timeval request_time[DISPLAYING_BUFFERS_MAX_NUM];
+#endif /* GST_EXT_XV_ENHANCEMENT */
 };
 
 GType gst_xvcontext_get_type (void);
@@ -243,7 +279,12 @@ void           gst_xwindow_clear                (GstXWindow * window);
 
 void           gst_xwindow_set_render_rectangle (GstXWindow * window,
                                                  gint x, gint y, gint width, gint height);
-
-
+#ifdef GST_EXT_XV_ENHANCEMENT
+gboolean gst_xvcontext_set_display_mode(GstXvContext *context, int set_mode);
+void gst_xvcontext_drm_init(GstXvContext *context);
+void gst_xvcontext_drm_fini(GstXvContext *context);
+void gst_xvcontext_add_displaying_buffer(GstXvContext *context, XV_DATA_PTR img_data, GstBuffer *buffer);
+void gst_xvcontext_remove_displaying_buffer(GstXvContext *context, unsigned int *gem_name);
+#endif /* GST_EXT_XV_ENHANCEMENT */
 
 #endif /* __GST_XVCONTEXT_H__ */
index 3aa1a82..818f4ef 100644 (file)
@@ -39,6 +39,9 @@
 
 /* Object header */
 #include "xvimageallocator.h"
+#ifdef GST_EXT_XV_ENHANCEMENT
+#include "xv_types.h"
+#endif /* GST_EXT_XV_ENHANCEMENT */
 
 /* Debugging category */
 #include <gst/gstinfo.h>
@@ -57,6 +60,10 @@ struct _GstXvImageMemory
   gint im_format;
   GstVideoRectangle crop;
 
+#ifdef GST_EXT_XV_ENHANCEMENT
+  GstBuffer *current_buffer;
+#endif /* GST_EXT_XV_ENHANCEMENT */
+
   XvImage *xvimage;
 
 #ifdef HAVE_XSHM
@@ -431,6 +438,17 @@ gst_xvimage_allocator_alloc (GstXvImageAllocator * allocator, gint im_format,
       case GST_MAKE_FOURCC ('U', 'Y', 'V', 'Y'):
         expected_size = padded_height * GST_ROUND_UP_4 (padded_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', 'N', '2', '1'):
+      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 /* GST_EXT_XV_ENHANCEMENT */
       default:
         expected_size = 0;
         break;
@@ -614,6 +632,11 @@ gst_xvimage_memory_render (GstXvImageMemory * mem, GstVideoRectangle * src_crop,
 {
   GstXvContext *context;
   XvImage *xvimage;
+#ifdef GST_EXT_XV_ENHANCEMENT
+  int ret           = 0;
+  int (*handler) (Display *, XErrorEvent *) = NULL;
+  XV_DATA_PTR img_data = NULL;
+#endif /* GST_EXT_XV_ENHANCEMENT */
 
   context = window->context;
 
@@ -629,12 +652,54 @@ gst_xvimage_memory_render (GstXvImageMemory * mem, GstVideoRectangle * src_crop,
         GST_PTR_FORMAT, src_crop->w, src_crop->h,
         window->render_rect.w, window->render_rect.h, mem);
 
+#ifdef GST_EXT_XV_ENHANCEMENT
+    /* set error handler */
+    error_caught = FALSE;
+    handler = XSetErrorHandler(gst_xvimage_handle_xerror);
+
+    /* src input indicates the status when degree is 0 */
+    /* dst input indicates the area that src will be shown regardless of rotate */
+    if (context->xim_transparenter) {
+      GST_LOG_OBJECT( mem, "Transparent related issue." );
+      XPutImage(context->disp,
+        window->win,
+        window->gc,
+        context->xim_transparenter,
+        0, 0,
+        dst_crop->x, dst_crop->y, dst_crop->w, dst_crop->h);
+    }
+
+    /* store buffer */
+    img_data = (XV_DATA_PTR) gst_xvimage_memory_get_xvimage(mem)->data;
+    if (img_data->BufType == XV_BUF_TYPE_DMABUF) {
+        gst_xvcontext_add_displaying_buffer(context, img_data, gst_xvimage_memory_get_buffer(mem));
+        gst_xvimage_memory_set_buffer(mem, NULL);
+    }
+
+    g_mutex_lock(context->display_buffer_lock);
+    if (context->displaying_buffer_count > 3) {
+      g_mutex_unlock(context->display_buffer_lock);
+      GST_WARNING("too many buffers are pushed. skip this... [displaying_buffer_count %d]",
+                  context->displaying_buffer_count);
+      ret = -1;
+    }
+    g_mutex_unlock(context->display_buffer_lock);
+
+    ret = XvShmPutImage (context->disp,
+      context->xv_port_id,
+      window->win,
+      window->gc, xvimage,
+      src_crop->x, src_crop->y, src_crop->w, src_crop->h,
+      dst_crop->x, dst_crop->y, dst_crop->w, dst_crop->h, FALSE);
+    GST_LOG_OBJECT( mem, "XvShmPutImage return value [%d]", ret );
+#else /* GST_EXT_XV_ENHANCEMENT */
     XvShmPutImage (context->disp,
         context->xv_port_id,
         window->win,
         window->gc, xvimage,
         src_crop->x, src_crop->y, src_crop->w, src_crop->h,
         dst_crop->x, dst_crop->y, dst_crop->w, dst_crop->h, FALSE);
+#endif /* GST_EXT_XV_ENHANCEMENT */
   } else
 #endif /* HAVE_XSHM */
   {
@@ -647,5 +712,40 @@ gst_xvimage_memory_render (GstXvImageMemory * mem, GstVideoRectangle * src_crop,
   }
   XSync (context->disp, FALSE);
 
+#ifdef HAVE_XSHM
+#ifdef GST_EXT_XV_ENHANCEMENT
+  if (ret || error_caught) {
+    GST_WARNING("putimage error : ret %d, error_caught %d, displaying buffer count %d",
+                ret, error_caught, context->displaying_buffer_count);
+
+  /* release gem handle */
+  img_data = (XV_DATA_PTR) gst_xvimage_memory_get_xvimage(mem)->data;
+  if (img_data && img_data->BufType == XV_BUF_TYPE_DMABUF) {
+    unsigned int gem_name[XV_BUF_PLANE_NUM] = { 0, };
+    gem_name[0] = img_data->YBuf;
+    gem_name[1] = img_data->CbBuf;
+    gem_name[2] = img_data->CrBuf;
+    gst_xvcontext_remove_displaying_buffer(context, gem_name);
+     }
+  }
+
+  /* Reset error handler */
+  error_caught = FALSE;
+  XSetErrorHandler (handler);
+#endif /* GST_EXT_XV_ENHANCEMENT */
+#endif /* HAVE_XSHM */
+
   g_mutex_unlock (&context->lock);
 }
+
+#ifdef GST_EXT_XV_ENHANCEMENT
+GstBuffer* gst_xvimage_memory_get_buffer(GstXvImageMemory *mem) {
+    g_return_val_if_fail (mem, NULL);
+    return mem->current_buffer;
+}
+
+void gst_xvimage_memory_set_buffer(GstXvImageMemory *mem, GstBuffer *new_buf) {
+    g_return_if_fail (mem);
+    mem->current_buffer = new_buf;
+}
+#endif /* GST_EXT_XV_ENHANCEMENT */
index c5fb9c8..775b2bd 100644 (file)
@@ -63,6 +63,10 @@ void                  gst_xvimage_memory_render         (GstXvImageMemory *mem,
                                                          GstXWindow *window,
                                                          GstVideoRectangle *dst_crop,
                                                          gboolean draw_border);
+#ifdef GST_EXT_XV_ENHANCEMENT
+GstBuffer *           gst_xvimage_memory_get_buffer(GstXvImageMemory *mem);
+void                  gst_xvimage_memory_set_buffer(GstXvImageMemory *mem, GstBuffer *new_buf);
+#endif /* GST_EXT_XV_ENHANCEMENT */
 
 G_END_DECLS
 
index 6bd5b3e..db95f36 100644 (file)
@@ -1,6 +1,7 @@
 /* GStreamer
  * Copyright (C) <2005> Julien Moutte <julien@moutte.net>
  *               <2009>,<2010> Stefan Kost <stefan.kost@nokia.com>
+ * Copyright (C) 2012, 2013 Samsung Electronics Co., Ltd.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
  * License along with this library; if not, write to the
  * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
  * Boston, MA 02110-1301, USA.
+ *
+ * Modifications by Samsung Electronics Co., Ltd.
+ * 1. Add display related properties
+ * 2. Support samsung extension format to improve performance
+ * 3. Support video texture overlay of OSP layer
  */
 
 /**
 #include "xvimagesink.h"
 #include "xvimageallocator.h"
 
+#ifdef GST_EXT_XV_ENHANCEMENT
+/* Samsung extension headers */
+/* For xv extension header for buffer transfer (output) */
+#include "xv_types.h"
+
+/* for performance checking */
+#include <mm_ta.h>
+
+typedef enum {
+        BUF_SHARE_METHOD_PADDR = 0,
+        BUF_SHARE_METHOD_FD,
+        BUF_SHARE_METHOD_TIZEN_BUFFER
+} buf_share_method_t;
+
+#define _EVENT_THREAD_CHECK_INTERVAL    15000   /* us */
+#endif /* GST_EXT_XV_ENHANCEMENT */
+
+
 /* Debugging category */
 #include <gst/gstinfo.h>
 
@@ -135,6 +159,189 @@ GST_DEBUG_CATEGORY_EXTERN (gst_debug_xvimagesink);
 GST_DEBUG_CATEGORY_EXTERN (GST_CAT_PERFORMANCE);
 #define GST_CAT_DEFAULT gst_debug_xvimagesink
 
+#ifdef GST_EXT_XV_ENHANCEMENT
+#define GST_TYPE_XVIMAGESINK_DISPLAY_MODE (gst_xvimagesink_display_mode_get_type())
+
+static GType
+gst_xvimagesink_display_mode_get_type(void)
+{
+   static GType xvimagesink_display_mode_type = 0;
+   static const GEnumValue display_mode_type[] = {
+       { 0, "Default mode", "DEFAULT"},
+       { 1, "Primary video ON and Secondary video FULL SCREEN mode", "PRI_VIDEO_ON_AND_SEC_VIDEO_FULL_SCREEN"},
+       { 2, "Primary video OFF and Secondary video FULL SCREEN mode", "PRI_VIDEO_OFF_AND_SEC_VIDEO_FULL_SCREEN"},
+       { 3, NULL, NULL},
+   };
+
+   if (!xvimagesink_display_mode_type) {
+       xvimagesink_display_mode_type = g_enum_register_static("GstXVImageSinkDisplayModeType", display_mode_type);
+   }
+
+   return xvimagesink_display_mode_type;
+}
+
+enum {
+    DEGREE_0,
+    DEGREE_90,
+    DEGREE_180,
+    DEGREE_270,
+    DEGREE_NUM,
+};
+
+#define GST_TYPE_XVIMAGESINK_ROTATE_ANGLE (gst_xvimagesink_rotate_angle_get_type())
+
+static GType
+gst_xvimagesink_rotate_angle_get_type(void)
+{
+   static GType xvimagesink_rotate_angle_type = 0;
+   static const GEnumValue rotate_angle_type[] = {
+       { 0, "No rotate", "DEGREE_0"},
+       { 1, "Rotate 90 degree", "DEGREE_90"},
+       { 2, "Rotate 180 degree", "DEGREE_180"},
+       { 3, "Rotate 270 degree", "DEGREE_270"},
+       { 4, NULL, NULL},
+   };
+
+   if (!xvimagesink_rotate_angle_type) {
+       xvimagesink_rotate_angle_type = g_enum_register_static("GstXVImageSinkRotateAngleType", rotate_angle_type);
+   }
+
+   return xvimagesink_rotate_angle_type;
+}
+
+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_ORIGIN_SIZE_OR_LETTER_BOX,
+    DISP_GEO_METHOD_CUSTOM_DST_ROI,
+    DISP_GEO_METHOD_NUM,
+};
+
+enum {
+    ROI_DISP_GEO_METHOD_FULL_SCREEN = 0,
+    ROI_DISP_GEO_METHOD_LETTER_BOX,
+    ROI_DISP_GEO_METHOD_NUM,
+};
+
+#define DEF_DISPLAY_GEOMETRY_METHOD         DISP_GEO_METHOD_LETTER_BOX
+#define DEF_ROI_DISPLAY_GEOMETRY_METHOD     ROI_DISP_GEO_METHOD_FULL_SCREEN
+
+enum {
+    FLIP_NONE = 0,
+    FLIP_HORIZONTAL,
+    FLIP_VERTICAL,
+    FLIP_BOTH,
+    FLIP_NUM,
+};
+#define DEF_DISPLAY_FLIP            FLIP_NONE
+
+#define GST_TYPE_XVIMAGESINK_DISPLAY_GEOMETRY_METHOD (gst_xvimagesink_display_geometry_method_get_type())
+#define GST_TYPE_XVIMAGESINK_ROI_DISPLAY_GEOMETRY_METHOD (gst_xvimagesink_roi_display_geometry_method_get_type())
+#define GST_TYPE_XVIMAGESINK_FLIP                    (gst_xvimagesink_flip_get_type())
+
+static GType
+gst_xvimagesink_display_geometry_method_get_type(void)
+{
+   static GType xvimagesink_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, "Origin size(if screen size is larger than video size(width/height)) or Letter box(if video size(width/height) is larger than screen size)", "ORIGIN_SIZE_OR_LETTER_BOX"},
+       { 5, "Explicitly described destination ROI", "CUSTOM_DST_ROI"},
+       { 6, NULL, NULL},
+   };
+
+   if (!xvimagesink_display_geometry_method_type) {
+       xvimagesink_display_geometry_method_type = g_enum_register_static("GstXVImageSinkDisplayGeometryMethodType", display_geometry_method_type);
+   }
+
+   return xvimagesink_display_geometry_method_type;
+}
+
+static GType
+gst_xvimagesink_roi_display_geometry_method_get_type(void)
+{
+       static GType xvimagesink_roi_display_geometry_method_type = 0;
+       static const GEnumValue roi_display_geometry_method_type[] = {
+               { 0, "ROI-Full-screen", "FULL_SCREEN"},
+               { 1, "ROI-Letter box", "LETTER_BOX"},
+               { 2, NULL, NULL},
+       };
+
+       if (!xvimagesink_roi_display_geometry_method_type) {
+               xvimagesink_roi_display_geometry_method_type = g_enum_register_static("GstXVImageSinkROIDisplayGeometryMethodType", roi_display_geometry_method_type);
+       }
+
+       return xvimagesink_roi_display_geometry_method_type;
+}
+
+static GType
+gst_xvimagesink_flip_get_type(void)
+{
+   static GType xvimagesink_flip_type = 0;
+   static const GEnumValue flip_type[] = {
+       { FLIP_NONE,       "Flip NONE", "FLIP_NONE"},
+       { FLIP_HORIZONTAL, "Flip HORIZONTAL", "FLIP_HORIZONTAL"},
+       { FLIP_VERTICAL,   "Flip VERTICAL", "FLIP_VERTICAL"},
+       { FLIP_BOTH,       "Flip BOTH", "FLIP_BOTH"},
+       { FLIP_NUM, NULL, NULL},
+   };
+
+   if (!xvimagesink_flip_type) {
+       xvimagesink_flip_type = g_enum_register_static("GstXVImageSinkFlipType", flip_type);
+   }
+
+   return xvimagesink_flip_type;
+}
+
+#define g_marshal_value_peek_pointer(v)  (v)->data[0].v_pointer
+void
+gst_xvimagesink_BOOLEAN__POINTER (GClosure         *closure,
+                                     GValue         *return_value G_GNUC_UNUSED,
+                                     guint          n_param_values,
+                                     const GValue   *param_values,
+                                     gpointer       invocation_hint G_GNUC_UNUSED,
+                                     gpointer       marshal_data)
+{
+  typedef gboolean (*GMarshalFunc_BOOLEAN__POINTER) (gpointer     data1,
+                                                     gpointer     arg_1,
+                                                     gpointer     data2);
+  register GMarshalFunc_BOOLEAN__POINTER callback;
+  register GCClosure *cc = (GCClosure*) closure;
+  register gpointer data1, data2;
+
+  gboolean v_return;
+
+  g_return_if_fail (return_value != NULL);
+  g_return_if_fail (n_param_values == 2);
+
+  if (G_CCLOSURE_SWAP_DATA (closure)) {
+    data1 = closure->data;
+    data2 = g_value_peek_pointer (param_values + 0);
+  } else {
+    data1 = g_value_peek_pointer (param_values + 0);
+    data2 = closure->data;
+  }
+  callback = (GMarshalFunc_BOOLEAN__POINTER) (marshal_data ? marshal_data : cc->callback);
+
+  v_return = callback (data1,
+                      g_marshal_value_peek_pointer (param_values + 1),
+                      data2);
+
+  g_value_set_boolean (return_value, v_return);
+}
+
+enum
+{
+    SIGNAL_FRAME_RENDER_ERROR,
+    LAST_SIGNAL
+};
+#endif /* GST_EXT_XV_ENHANCEMENT */
+
 typedef struct
 {
   unsigned long flags;
@@ -184,7 +391,23 @@ enum
   PROP_COLORKEY,
   PROP_DRAW_BORDERS,
   PROP_WINDOW_WIDTH,
-  PROP_WINDOW_HEIGHT
+  PROP_WINDOW_HEIGHT,
+#ifdef GST_EXT_XV_ENHANCEMENT
+  PROP_DISPLAY_MODE,
+  PROP_ROTATE_ANGLE,
+  PROP_FLIP,
+  PROP_DISPLAY_GEOMETRY_METHOD,
+  PROP_VISIBLE,
+  PROP_ZOOM,
+  PROP_ZOOM_POS_X,
+  PROP_ZOOM_POS_Y,
+  PROP_ORIENTATION,
+  PROP_DST_ROI_MODE,
+  PROP_DST_ROI_X,
+  PROP_DST_ROI_Y,
+  PROP_DST_ROI_W,
+  PROP_DST_ROI_H,
+#endif /* GST_EXT_XV_ENHANCEMENT */
 };
 
 /* ============================================================= */
@@ -232,11 +455,37 @@ gst_xvimagesink_xvimage_put (GstXvImageSink * xvimagesink, GstBuffer * xvimage)
   GstVideoRectangle src, dst;
   GstVideoRectangle mem_crop;
   GstXWindow *xwindow;
+#ifdef GST_EXT_XV_ENHANCEMENT
+  static Atom atom_rotation = None;
+  static Atom atom_hflip = None;
+  static Atom atom_vflip = None;
+  gboolean set_hflip = FALSE;
+  gboolean set_vflip = FALSE;
+
+  GstVideoRectangle src_origin = { 0, 0, 0, 0};
+  GstVideoRectangle src_input  = { 0, 0, 0, 0};
+
+  gint res_rotate_angle = 0;
+  int rotate        = 0;
+  int ret           = 0;
+
+  gst_xvimagesink_xwindow_update_geometry( xvimagesink );
+#endif /* GST_EXT_XV_ENHANCEMENT */
 
   /* 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 (&xvimagesink->flow_lock);
 
+#ifdef GST_EXT_XV_ENHANCEMENT
+  if (xvimagesink->xid_updated) {
+    if (xvimage) {
+      GST_WARNING_OBJECT (xvimagesink, "set xvimage to NULL, new xid was set right after creation of new xvimage");
+      xvimage = NULL;
+    }
+    xvimagesink->xid_updated = FALSE;
+  }
+#endif /* GST_EXT_XV_ENHANCEMENT */
+
   if (G_UNLIKELY ((xwindow = xvimagesink->xwindow) == NULL)) {
     g_mutex_unlock (&xvimagesink->flow_lock);
     return FALSE;
@@ -265,12 +514,333 @@ gst_xvimagesink_xvimage_put (GstXvImageSink * xvimagesink, GstBuffer * xvimage)
       draw_border = TRUE;
       xvimage = xvimagesink->cur_image;
     } else {
+#ifdef GST_EXT_XV_ENHANCEMENT
+      GST_WARNING_OBJECT(xvimagesink, "cur_image is NULL. Skip xvimage_put.");
+      /* no need to release gem handle */
+#endif /* GST_EXT_XV_ENHANCEMENT */
       g_mutex_unlock (&xvimagesink->flow_lock);
       return TRUE;
     }
   }
 
   mem = (GstXvImageMemory *) gst_buffer_peek_memory (xvimage, 0);
+#ifdef GST_EXT_XV_ENHANCEMENT
+  if (!xvimagesink->visible) {
+    GST_INFO("visible[%d]. Skip xvimage_put.",
+             xvimagesink->visible);
+    g_mutex_unlock(&xvimagesink->flow_lock);
+    return TRUE;
+  }
+
+  res_rotate_angle = xvimagesink->rotate_angle;
+
+  src.x = src.y = 0;
+  src_origin.x = src_origin.y = src_input.x = src_input.y = 0;
+
+  src_input.w = src_origin.w = xvimagesink->video_width;
+  src_input.h = src_origin.h = xvimagesink->video_height;
+
+  if (xvimagesink->rotate_angle == DEGREE_0 ||
+      xvimagesink->rotate_angle == DEGREE_180) {
+    src.w = src_origin.w;
+    src.h = src_origin.h;
+  } else {
+    src.w = src_origin.h;
+    src.h = src_origin.w;
+  }
+
+  dst.w = xwindow->render_rect.w;
+  dst.h = xwindow->render_rect.h;
+
+  switch (xvimagesink->display_geometry_method)
+  {
+    case DISP_GEO_METHOD_LETTER_BOX:
+      gst_video_sink_center_rect (src, dst, &result, TRUE);
+      result.x += xwindow->render_rect.x;
+      result.y += xwindow->render_rect.y;
+      break;
+
+    case DISP_GEO_METHOD_ORIGIN_SIZE_OR_LETTER_BOX:
+      GST_WARNING_OBJECT(xvimagesink, "not supported API, set ORIGIN_SIZE mode");
+    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);
+
+      if (xvimagesink->rotate_angle == DEGREE_90 ||
+          xvimagesink->rotate_angle == DEGREE_270) {
+        src_input.x = src_input.x ^ src_input.y;
+        src_input.y = src_input.x ^ src_input.y;
+        src_input.x = src_input.x ^ src_input.y;
+
+        src_input.w = src_input.w ^ src_input.h;
+        src_input.h = src_input.w ^ src_input.h;
+        src_input.w = src_input.w ^ src_input.h;
+      }
+      break;
+
+   case DISP_GEO_METHOD_FULL_SCREEN:
+      result.x = result.y = 0;
+      result.w = xwindow->width;
+      result.h = xwindow->height;
+      break;
+
+   case DISP_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;
+
+      if (xvimagesink->rotate_angle == DEGREE_90 ||
+          xvimagesink->rotate_angle == DEGREE_270) {
+        src_input.x = src_input.x ^ src_input.y;
+        src_input.y = src_input.x ^ src_input.y;
+        src_input.x = src_input.x ^ src_input.y;
+
+        src_input.w = src_input.w ^ src_input.h;
+        src_input.h = src_input.w ^ src_input.h;
+        src_input.w = src_input.w ^ src_input.h;
+      }
+      break;
+
+    case DISP_GEO_METHOD_CUSTOM_DST_ROI:
+    {
+      GstVideoRectangle dst_roi_cmpns;
+      dst_roi_cmpns.w = xvimagesink->dst_roi.w;
+      dst_roi_cmpns.h = xvimagesink->dst_roi.h;
+      dst_roi_cmpns.x = xvimagesink->dst_roi.x;
+      dst_roi_cmpns.y = xvimagesink->dst_roi.y;
+
+      /* setting for DST ROI mode */
+      switch (xvimagesink->dst_roi_mode) {
+      case ROI_DISP_GEO_METHOD_FULL_SCREEN:
+        break;
+      case ROI_DISP_GEO_METHOD_LETTER_BOX:
+       {
+        GstVideoRectangle roi_result;
+        if (xvimagesink->orientation == DEGREE_0 ||
+            xvimagesink->orientation == DEGREE_180) {
+          src.w = src_origin.w;
+          src.h = src_origin.h;
+        } else {
+          src.w = src_origin.h;
+          src.h = src_origin.w;
+        }
+        dst.w = xvimagesink->dst_roi.w;
+        dst.h = xvimagesink->dst_roi.h;
+
+        gst_video_sink_center_rect (src, dst, &roi_result, TRUE);
+        dst_roi_cmpns.w = roi_result.w;
+        dst_roi_cmpns.h = roi_result.h;
+        dst_roi_cmpns.x = xvimagesink->dst_roi.x + roi_result.x;
+        dst_roi_cmpns.y = xvimagesink->dst_roi.y + roi_result.y;
+       }
+        break;
+      default:
+        break;
+      }
+
+      /* calculating coordinates according to rotation angle for DST ROI */
+      switch (xvimagesink->rotate_angle) {
+      case DEGREE_90:
+        result.w = dst_roi_cmpns.h;
+        result.h = dst_roi_cmpns.w;
+
+        result.x = dst_roi_cmpns.y;
+        result.y = xvimagesink->xwindow->height - dst_roi_cmpns.x - dst_roi_cmpns.w;
+        break;
+      case DEGREE_180:
+        result.w = dst_roi_cmpns.w;
+        result.h = dst_roi_cmpns.h;
+
+        result.x = xvimagesink->xwindow->width - result.w - dst_roi_cmpns.x;
+        result.y = xvimagesink->xwindow->height - result.h - dst_roi_cmpns.y;
+        break;
+      case DEGREE_270:
+        result.w = dst_roi_cmpns.h;
+        result.h = dst_roi_cmpns.w;
+
+        result.x = xvimagesink->xwindow->width - dst_roi_cmpns.y - dst_roi_cmpns.h;
+        result.y = dst_roi_cmpns.x;
+        break;
+      default:
+        result.x = dst_roi_cmpns.x;
+        result.y = dst_roi_cmpns.y;
+        result.w = dst_roi_cmpns.w;
+        result.h = dst_roi_cmpns.h;
+        break;
+      }
+
+      /* orientation setting for auto rotation in DST ROI */
+      if (xvimagesink->orientation) {
+        res_rotate_angle = (xvimagesink->rotate_angle - xvimagesink->orientation);
+        if (res_rotate_angle < 0) {
+          res_rotate_angle += DEGREE_NUM;
+        }
+        GST_LOG_OBJECT(xvimagesink, "changing rotation value internally by ROI orientation[%d] : rotate[%d->%d]",
+                     xvimagesink->orientation, xvimagesink->rotate_angle, res_rotate_angle);
+      }
+
+      GST_LOG_OBJECT(xvimagesink, "rotate[%d], dst ROI: orientation[%d], mode[%d], input[%d,%d,%dx%d]->result[%d,%d,%dx%d]",
+                     xvimagesink->rotate_angle, xvimagesink->orientation, xvimagesink->dst_roi_mode,
+                     xvimagesink->dst_roi.x, xvimagesink->dst_roi.y, xvimagesink->dst_roi.w, xvimagesink->dst_roi.h,
+                     result.x, result.y, result.w, result.h);
+      break;
+    }
+    default:
+      break;
+  }
+
+  if (xvimagesink->zoom > 1.0 && xvimagesink->zoom <= 9.0) {
+    GST_LOG_OBJECT(xvimagesink, "before zoom[%lf], src_input[x:%d,y:%d,w:%d,h:%d]",
+                   xvimagesink->zoom, src_input.x, src_input.y, src_input.w, src_input.h);
+    gint default_offset_x = 0;
+    gint default_offset_y = 0;
+    gfloat w = (gfloat)src_input.w;
+    gfloat h = (gfloat)src_input.h;
+    if (xvimagesink->orientation == DEGREE_0 ||
+        xvimagesink->orientation == DEGREE_180) {
+      default_offset_x = ((gint)(w - (w/xvimagesink->zoom)))>>1;
+      default_offset_y = ((gint)(h - (h/xvimagesink->zoom)))>>1;
+    } else {
+      default_offset_y = ((gint)(w - (w/xvimagesink->zoom)))>>1;
+      default_offset_x = ((gint)(h - (h/xvimagesink->zoom)))>>1;
+    }
+    GST_LOG_OBJECT(xvimagesink, "default offset x[%d] y[%d], orientation[%d]", default_offset_x, default_offset_y, xvimagesink->orientation);
+    if (xvimagesink->zoom_pos_x == -1) {
+      src_input.x += default_offset_x;
+    } else {
+      if (xvimagesink->orientation == DEGREE_0 ||
+          xvimagesink->orientation == DEGREE_180) {
+        if ((w/xvimagesink->zoom) > w - xvimagesink->zoom_pos_x) {
+          xvimagesink->zoom_pos_x = w - (w/xvimagesink->zoom);
+        }
+        src_input.x += xvimagesink->zoom_pos_x;
+      } else {
+        if ((h/xvimagesink->zoom) > h - xvimagesink->zoom_pos_x) {
+          xvimagesink->zoom_pos_x = h - (h/xvimagesink->zoom);
+        }
+        src_input.y += (h - h/xvimagesink->zoom) - xvimagesink->zoom_pos_x;
+      }
+    }
+    if (xvimagesink->zoom_pos_y == -1) {
+      src_input.y += default_offset_y;
+    } else {
+      if (xvimagesink->orientation == DEGREE_0 ||
+          xvimagesink->orientation == DEGREE_180) {
+        if ((h/xvimagesink->zoom) > h - xvimagesink->zoom_pos_y) {
+          xvimagesink->zoom_pos_y = h - (h/xvimagesink->zoom);
+        }
+        src_input.y += xvimagesink->zoom_pos_y;
+      } else {
+        if ((w/xvimagesink->zoom) > w - xvimagesink->zoom_pos_y) {
+          xvimagesink->zoom_pos_y = w - (w/xvimagesink->zoom);
+        }
+        src_input.x += (xvimagesink->zoom_pos_y);
+      }
+    }
+    src_input.w = (gint)(w/xvimagesink->zoom);
+    src_input.h = (gint)(h/xvimagesink->zoom);
+    GST_LOG_OBJECT(xvimagesink, "after zoom[%lf], src_input[x:%d,y:%d,w:%d,h%d], zoom_pos[x:%d,y:%d]",
+                   xvimagesink->zoom, src_input.x, src_input.y, src_input.w, src_input.h, xvimagesink->zoom_pos_x, xvimagesink->zoom_pos_y);
+  }
+
+  switch( res_rotate_angle )
+  {
+    /* There's slightly weired code (CCW? CW?) */
+    case DEGREE_0:
+      break;
+    case DEGREE_90:
+      rotate = 270;
+      break;
+    case DEGREE_180:
+      rotate = 180;
+      break;
+    case DEGREE_270:
+      rotate = 90;
+      break;
+    default:
+      GST_WARNING_OBJECT( xvimagesink, "Unsupported rotation [%d]... set DEGREE 0.",
+          res_rotate_angle );
+      break;
+  }
+
+  /* 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( xvimagesink, "window[%dx%d],method[%d],rotate[%d],zoom[%d],dp_mode[%d],src[%dx%d],dst[%d,%d,%dx%d],input[%d,%d,%dx%d],result[%d,%d,%dx%d]",
+    xwindow->width, xwindow->height,
+    xvimagesink->display_geometry_method, rotate, xvimagesink->zoom, xvimagesink->config.display_mode,
+    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 );
+
+  memcpy (&src, &src_input, sizeof (src_input));
+
+#ifdef HAVE_XSHM
+  /* set display rotation */
+  if (atom_rotation == None) {
+    atom_rotation = XInternAtom(xvimagesink->context->disp,
+                                "_USER_WM_PORT_ATTRIBUTE_ROTATION", False);
+  }
+
+  GST_LOG("set HFLIP %d, VFLIP %d", set_hflip, set_vflip);
+
+  ret = XvSetPortAttribute(xvimagesink->context->disp, xvimagesink->context->xv_port_id, atom_rotation, rotate);
+  if (ret != Success) {
+    GST_ERROR_OBJECT( mem, "XvSetPortAttribute failed[%d]. disp[%x],xv_port_id[%d],atom[%x],rotate[%d]",
+      ret, xvimagesink->context->disp, xvimagesink->context->xv_port_id, atom_rotation, rotate );
+    return ret;
+  }
+
+  /* set display flip */
+  if (atom_hflip == None) {
+    atom_hflip = XInternAtom(xvimagesink->context->disp,
+                             "_USER_WM_PORT_ATTRIBUTE_HFLIP", False);
+  }
+  if (atom_vflip == None) {
+    atom_vflip = XInternAtom(xvimagesink->context->disp,
+                             "_USER_WM_PORT_ATTRIBUTE_VFLIP", False);
+  }
+
+  switch (xvimagesink->flip) {
+  case FLIP_HORIZONTAL:
+    set_hflip = TRUE;
+    set_vflip = FALSE;
+    break;
+  case FLIP_VERTICAL:
+    set_hflip = FALSE;
+    set_vflip = TRUE;
+    break;
+  case FLIP_BOTH:
+    set_hflip = TRUE;
+    set_vflip = TRUE;
+    break;
+  case FLIP_NONE:
+  default:
+    set_hflip = FALSE;
+    set_vflip = FALSE;
+    break;
+  }
+
+  ret = XvSetPortAttribute(xvimagesink->context->disp, xvimagesink->context->xv_port_id, atom_hflip, set_hflip);
+  if (ret != Success) {
+    GST_WARNING("set HFLIP failed[%d]. disp[%x],xv_port_id[%d],atom[%x],hflip[%d]",
+                ret, xvimagesink->context->disp, xvimagesink->context->xv_port_id, atom_hflip, set_hflip);
+  }
+  ret = XvSetPortAttribute(xvimagesink->context->disp, xvimagesink->context->xv_port_id, atom_vflip, set_vflip);
+  if (ret != Success) {
+    GST_WARNING("set VFLIP failed[%d]. disp[%x],xv_port_id[%d],atom[%x],vflip[%d]",
+                ret, xvimagesink->context->disp, xvimagesink->context->xv_port_id, atom_vflip, set_vflip);
+  }
+#endif /* HAVE_XSHM */
+#else /* GST_EXT_XV_ENHANCEMENT */
   gst_xvimage_memory_get_crop (mem, &mem_crop);
 
   crop = gst_buffer_get_video_crop_meta (xvimage);
@@ -303,6 +873,7 @@ gst_xvimagesink_xvimage_put (GstXvImageSink * xvimagesink, GstBuffer * xvimage)
   } else {
     memcpy (&result, &xwindow->render_rect, sizeof (GstVideoRectangle));
   }
+#endif /* GST_EXT_XV_ENHANCEMENT */
 
   gst_xvimage_memory_render (mem, &src, xwindow, &result, draw_border);
 
@@ -355,7 +926,17 @@ gst_xvimagesink_xwindow_new (GstXvImageSink * xvimagesink,
 
   context = xvimagesink->context;
 
+#ifdef GST_EXT_XV_ENHANCEMENT
+  /* 0 or 180 */
+  if (xvimagesink->rotate_angle == 0 || xvimagesink->rotate_angle == 2) {
+      xwindow = gst_xvcontext_create_xwindow (context, height, width);
+  /* 90 or 270 */
+  } else {
+      xwindow = gst_xvcontext_create_xwindow (context, width, height);
+  }
+#else
   xwindow = gst_xvcontext_create_xwindow (context, width, height);
+#endif /* GST_EXT_XV_ENHANCEMENT */
 
   /* set application name as a title */
   gst_xvimagesink_xwindow_set_title (xvimagesink, xwindow, NULL);
@@ -410,6 +991,10 @@ gst_xvimagesink_handle_xevents (GstXvImageSink * xvimagesink)
 
   g_return_if_fail (GST_IS_XVIMAGESINK (xvimagesink));
 
+#ifdef GST_EXT_XV_ENHANCEMENT
+  GST_LOG("check x event");
+#endif /* GST_EXT_XV_ENHANCEMENT */
+
   /* Handle Interaction, produces navigation events */
 
   /* We get all pointer motion events, only the last position is
@@ -514,8 +1099,13 @@ gst_xvimagesink_handle_xevents (GstXvImageSink * xvimagesink)
         g_mutex_unlock (&xvimagesink->context->lock);
         g_mutex_unlock (&xvimagesink->flow_lock);
 
+#ifdef GST_EXT_XV_ENHANCEMENT
+        GST_WARNING("Call gst_xvimagesink_xwindow_update_geometry!");
+#endif /* GST_EXT_XV_ENHANCEMENT */
         gst_xvimagesink_xwindow_update_geometry (xvimagesink);
-
+#ifdef GST_EXT_XV_ENHANCEMENT
+        GST_WARNING("Return gst_xvimagesink_xwindow_update_geometry!");
+#endif /* GST_EXT_XV_ENHANCEMENT */
         g_mutex_lock (&xvimagesink->flow_lock);
         g_mutex_lock (&xvimagesink->context->lock);
         configured = TRUE;
@@ -541,8 +1131,28 @@ gst_xvimagesink_handle_xevents (GstXvImageSink * xvimagesink)
 
     switch (e.type) {
       case ClientMessage:{
+#ifdef GST_EXT_XV_ENHANCEMENT
+        XClientMessageEvent *cme = (XClientMessageEvent *)&e;
+        Atom buffer_atom = XInternAtom(xvimagesink->context->disp, "XV_RETURN_BUFFER", False);
+#endif /* GST_EXT_XV_ENHANCEMENT */
         Atom wm_delete;
 
+#ifdef GST_EXT_XV_ENHANCEMENT
+        GST_LOG_OBJECT(xvimagesink, "message type %d, buffer atom %d", cme->message_type, buffer_atom);
+        if (cme->message_type == buffer_atom) {
+          unsigned int gem_name[XV_BUF_PLANE_NUM] = { 0, };
+
+          GST_DEBUG("data.l[0] -> %d, data.l[1] -> %d",
+                    cme->data.l[0], cme->data.l[1]);
+
+          gem_name[0] = cme->data.l[0];
+          gem_name[1] = cme->data.l[1];
+
+          gst_xvcontext_remove_displaying_buffer(xvimagesink->context, gem_name);
+          break;
+        }
+#endif /* GST_EXT_XV_ENHANCEMENT */
+
         wm_delete = XInternAtom (xvimagesink->context->disp,
             "WM_DELETE_WINDOW", True);
         if (wm_delete != None && wm_delete == (Atom) e.xclient.data.l[0]) {
@@ -578,8 +1188,13 @@ gst_xvimagesink_event_thread (GstXvImageSink * xvimagesink)
     if (xvimagesink->xwindow) {
       gst_xvimagesink_handle_xevents (xvimagesink);
     }
+
+#ifdef GST_EXT_XV_ENHANCEMENT
+    g_usleep (_EVENT_THREAD_CHECK_INTERVAL);
+#else /* GST_EXT_XV_ENHANCEMENT */
     /* FIXME: do we want to align this with the framerate or anything else? */
     g_usleep (G_USEC_PER_SEC / 20);
+#endif /* GST_EXT_XV_ENHANCEMENT */
 
     GST_OBJECT_LOCK (xvimagesink);
   }
@@ -840,12 +1455,21 @@ gst_xvimagesink_change_state (GstElement * element, GstStateChange transition)
 
   switch (transition) {
     case GST_STATE_CHANGE_NULL_TO_READY:
+#ifdef GST_EXT_XV_ENHANCEMENT
+      GST_WARNING("NULL_TO_READY start");
+#endif /* GST_EXT_XV_ENHANCEMENT */
       if (!gst_xvimagesink_open (xvimagesink))
         goto error;
+#ifdef GST_EXT_XV_ENHANCEMENT
+      GST_WARNING("NULL_TO_READY done");
+#endif /* GST_EXT_XV_ENHANCEMENT */
       break;
     case GST_STATE_CHANGE_READY_TO_PAUSED:
       break;
     case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
+#ifdef GST_EXT_XV_ENHANCEMENT
+        GST_WARNING("PAUSED_TO_PLAYING done");
+#endif /* GST_EXT_XV_ENHANCEMENT */
       break;
     case GST_STATE_CHANGE_PAUSED_TO_READY:
       break;
@@ -857,6 +1481,13 @@ gst_xvimagesink_change_state (GstElement * element, GstStateChange transition)
 
   switch (transition) {
     case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
+#ifdef GST_EXT_XV_ENHANCEMENT
+      GST_WARNING("PLAYING_TO_PAUSED start");
+      /* init displayed buffer count */
+      xvimagesink->context->displayed_buffer_count = 0;
+
+      GST_WARNING("PLAYING_TO_PAUSED done");
+#endif /* GST_EXT_XV_ENHANCEMENT */
       break;
     case GST_STATE_CHANGE_PAUSED_TO_READY:
       xvimagesink->fps_n = 0;
@@ -867,9 +1498,21 @@ gst_xvimagesink_change_state (GstElement * element, GstStateChange transition)
       if (xvimagesink->pool)
         gst_buffer_pool_set_active (xvimagesink->pool, FALSE);
       g_mutex_unlock (&xvimagesink->flow_lock);
+#ifdef GST_EXT_XV_ENHANCEMENT
+      /* close drm */
+      gst_xvcontext_drm_fini(xvimagesink->context);
+
+      GST_WARNING("PAUSED_TO_READY done");
+#endif /* GST_EXT_XV_ENHANCEMENT */
       break;
     case GST_STATE_CHANGE_READY_TO_NULL:
+#ifdef GST_EXT_XV_ENHANCEMENT
+      GST_WARNING("READY_TO_NULL start");
+#endif /* GST_EXT_XV_ENHANCEMENT */
       gst_xvimagesink_close (xvimagesink);
+#ifdef GST_EXT_XV_ENHANCEMENT
+      GST_WARNING("READY_TO_NULL done");
+#endif /* GST_EXT_XV_ENHANCEMENT */
       break;
     default:
       break;
@@ -911,6 +1554,11 @@ gst_xvimagesink_show_frame (GstVideoSink * vsink, GstBuffer * buf)
   GstXvImageSink *xvimagesink;
   GstBuffer *to_put = NULL;
   GstMemory *mem;
+  gboolean ret = FALSE;
+#ifdef GST_EXT_XV_ENHANCEMENT
+  GstMapInfo mem_info = GST_MAP_INFO_INIT;
+  SCMN_IMGB *scmn_imgb = NULL;
+#endif /* GST_EXT_XV_ENHANCEMENT */
 
   xvimagesink = GST_XVIMAGESINK (vsink);
 
@@ -920,6 +1568,9 @@ gst_xvimagesink_show_frame (GstVideoSink * vsink, GstBuffer * buf)
        put the ximage which is in the PRIVATE pointer */
     GST_LOG_OBJECT (xvimagesink, "buffer %p from our pool, writing directly",
         buf);
+#ifdef GST_EXT_XV_ENHANCEMENT
+    xvimagesink->xid_updated = FALSE;
+#endif /* GST_EXT_XV_ENHANCEMENT */
     to_put = buf;
     res = GST_FLOW_OK;
   } else {
@@ -947,7 +1598,115 @@ gst_xvimagesink_show_frame (GstVideoSink * vsink, GstBuffer * buf)
 
     GST_CAT_LOG_OBJECT (GST_CAT_PERFORMANCE, xvimagesink,
         "slow copy buffer %p into bufferpool buffer %p", buf, to_put);
+#ifdef GST_EXT_XV_ENHANCEMENT
+    switch (GST_VIDEO_INFO_FORMAT(&xvimagesink->info)) {
+      /* Cases for specified formats of Samsung extension */
+     case GST_VIDEO_FORMAT_SN12:
+     case GST_VIDEO_FORMAT_ST12:
+     case GST_VIDEO_FORMAT_ITLV:
+     {
+       GstXvImageMemory* img_mem = NULL;
+       XV_DATA_PTR img_data = NULL;
+
+       GST_LOG("Samsung EXT format - name:%s, display mode:%d, Rotate angle:%d", GST_VIDEO_INFO_NAME(&xvimagesink->info),
+               xvimagesink->config.display_mode, xvimagesink->rotate_angle);
+
+       img_mem = (GstXvImageMemory*)gst_buffer_peek_memory(to_put, 0);
+       img_data = (XV_DATA_PTR) gst_xvimage_memory_get_xvimage(img_mem)->data;
+       if (img_data) {
+         memset(img_data, 0x0, sizeof(XV_DATA));
+         XV_INIT_DATA(img_data);
+
+         mem = gst_buffer_peek_memory(buf, 1);
+         gst_memory_map(mem, &mem_info, GST_MAP_READ);
+         scmn_imgb = (SCMN_IMGB *)mem_info.data;
+         gst_memory_unmap(mem, &mem_info);
+         if (scmn_imgb == NULL) {
+           GST_DEBUG_OBJECT( xvimagesink, "scmn_imgb is NULL. Skip xvimage put..." );
+           g_mutex_unlock (&xvimagesink->flow_lock);
+           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;
+         } else if (scmn_imgb->buf_share_method == BUF_SHARE_METHOD_FD) {
+           /* open drm to use gem */
+           if (xvimagesink->context->drm_fd < 0) {
+               gst_xvcontext_drm_init(xvimagesink->context);
+           }
+
+           if (scmn_imgb->buf_share_method == BUF_SHARE_METHOD_FD) {
+             /* keep dma-buf fd. fd will be converted in gst_xvimagesink_xvimage_put */
+             img_data->dmabuf_fd[0] = scmn_imgb->dmabuf_fd[0];
+             img_data->dmabuf_fd[1] = scmn_imgb->dmabuf_fd[1];
+             img_data->dmabuf_fd[2] = scmn_imgb->dmabuf_fd[2];
+             img_data->BufType = XV_BUF_TYPE_DMABUF;
+             GST_DEBUG("DMABUF fd %u,%u,%u", img_data->dmabuf_fd[0], img_data->dmabuf_fd[1], img_data->dmabuf_fd[2]);
+           } else {
+             /* keep bo. bo will be converted in gst_xvimagesink_xvimage_put */
+             img_data->bo[0] = scmn_imgb->bo[0];
+             img_data->bo[1] = scmn_imgb->bo[1];
+             img_data->bo[2] = scmn_imgb->bo[2];
+             GST_DEBUG("TBM bo %p %p %p", img_data->bo[0], img_data->bo[1], img_data->bo[2]);
+           }
+
+           /* check secure contents path */
+           /* NOTE : does it need to set 0 during playing(recovery case)? */
+           if (scmn_imgb->tz_enable) {
+             if (!xvimagesink->is_secure_path) {
+               Atom atom_secure = None;
+               g_mutex_lock (&xvimagesink->context->lock);
+               atom_secure = XInternAtom(xvimagesink->context->disp, "_USER_WM_PORT_ATTRIBUTE_SECURE", False);
+               if (atom_secure != None) {
+                 if (XvSetPortAttribute(xvimagesink->context->disp, xvimagesink->context->xv_port_id, atom_secure, 1) != Success) {
+                   GST_ERROR_OBJECT(xvimagesink, "%d: XvSetPortAttribute: secure setting failed.\n", atom_secure);
+                 } else {
+                   GST_WARNING_OBJECT(xvimagesink, "secure contents path is enabled.\n");
+                 }
+                   XSync (xvimagesink->context->disp, FALSE);
+               }
+               g_mutex_unlock (&xvimagesink->context->lock);
+               xvimagesink->is_secure_path = TRUE;
+             }
+           }
+
+           /* set current buffer */
+           gst_xvimage_memory_set_buffer(img_mem, buf);
+        } else {
+          GST_WARNING("unknown buf_share_method type [%d]. skip xvimage put...",
+                      scmn_imgb->buf_share_method);
+          g_mutex_unlock (&xvimagesink->flow_lock);
+          return GST_FLOW_OK;
+        }
 
+       } else {
+          GST_WARNING_OBJECT( xvimagesink, "xvimage->data is NULL. skip xvimage put..." );
+          return GST_FLOW_OK;
+        }
+        break;
+      }
+      default:
+      {
+        GST_DEBUG("Normal format activated. Name = %s", GST_VIDEO_INFO_NAME(&xvimagesink->info));
+        if (!gst_video_frame_map (&src, &xvimagesink->info, buf, GST_MAP_READ))
+          goto invalid_buffer;
+
+        if (!gst_video_frame_map (&dest, &xvimagesink->info, to_put, GST_MAP_WRITE)) {
+          gst_video_frame_unmap (&src);
+          goto invalid_buffer;
+        }
+
+        gst_video_frame_copy (&dest, &src);
+
+        gst_video_frame_unmap (&dest);
+        gst_video_frame_unmap (&src);
+        break;
+      }
+    }
+#else /* GST_EXT_XV_ENHANCEMENT */
     if (!gst_video_frame_map (&src, &xvimagesink->info, buf, GST_MAP_READ))
       goto invalid_buffer;
 
@@ -960,10 +1719,14 @@ gst_xvimagesink_show_frame (GstVideoSink * vsink, GstBuffer * buf)
 
     gst_video_frame_unmap (&dest);
     gst_video_frame_unmap (&src);
+#endif /* GST_EXT_XV_ENHANCEMENT */
   }
 
-  if (!gst_xvimagesink_xvimage_put (xvimagesink, to_put))
+  ret = gst_xvimagesink_xvimage_put(xvimagesink, to_put);
+
+  if (!ret) {
     goto no_window;
+  }
 
 done:
   if (to_put != buf)
@@ -1197,11 +1960,20 @@ gst_xvimagesink_set_window_handle (GstVideoOverlay * overlay, guintptr id)
   GstXvImageSink *xvimagesink = GST_XVIMAGESINK (overlay);
   GstXWindow *xwindow = NULL;
   GstXvContext *context;
+#ifdef GST_EXT_XV_ENHANCEMENT
+  GstState current_state = GST_STATE_NULL;
+#endif /* GST_EXT_XV_ENHANCEMENT */
 
   g_return_if_fail (GST_IS_XVIMAGESINK (xvimagesink));
 
   g_mutex_lock (&xvimagesink->flow_lock);
 
+#ifdef GST_EXT_XV_ENHANCEMENT
+  gst_element_get_state(GST_ELEMENT(xvimagesink), &current_state, NULL, 0);
+  GST_WARNING_OBJECT(xvimagesink, "ENTER, id : %d, current state : %d",
+                                  xwindow_id, current_state);
+#endif /* GST_EXT_XV_ENHANCEMENT */
+
   /* If we already use that window return */
   if (xvimagesink->xwindow && (xwindow_id == xvimagesink->xwindow->win)) {
     g_mutex_unlock (&xvimagesink->flow_lock);
@@ -1246,7 +2018,24 @@ gst_xvimagesink_set_window_handle (GstVideoOverlay * overlay, guintptr id)
   if (xwindow)
     xvimagesink->xwindow = xwindow;
 
+#ifdef GST_EXT_XV_ENHANCEMENT
+  xvimagesink->xid_updated = TRUE;
+#endif /* GST_EXT_XV_ENHANCEMENT */
+
   g_mutex_unlock (&xvimagesink->flow_lock);
+
+#ifdef GST_EXT_XV_ENHANCEMENT
+  if (current_state == GST_STATE_PAUSED) {
+    GstBuffer *last_buffer = NULL;
+    g_object_get(G_OBJECT(xvimagesink), "last-buffer", &last_buffer, NULL);
+    GST_WARNING_OBJECT(xvimagesink, "PASUED state: window handle is updated. last buffer %p", last_buffer);
+    if (last_buffer) {
+      gst_xvimagesink_show_frame((GstVideoSink *)xvimagesink, last_buffer);
+      gst_buffer_unref(last_buffer);
+      last_buffer = NULL;
+    }
+  }
+#endif /* GST_EXT_XV_ENHANCEMENT */
 }
 
 static void
@@ -1630,6 +2419,130 @@ gst_xvimagesink_set_property (GObject * object, guint prop_id,
     case PROP_DRAW_BORDERS:
       xvimagesink->draw_borders = g_value_get_boolean (value);
       break;
+#ifdef GST_EXT_XV_ENHANCEMENT
+    case PROP_DISPLAY_MODE:
+    {
+      int set_mode = g_value_get_enum (value);
+
+      g_mutex_lock(&xvimagesink->flow_lock);
+      g_mutex_lock(&xvimagesink->context->lock);
+
+      if (xvimagesink->config.display_mode != set_mode) {
+        if (xvimagesink->context) {
+          /* set display mode */
+          if (gst_xvcontext_set_display_mode(xvimagesink->context, set_mode)) {
+            xvimagesink->config.display_mode = set_mode;
+          } else {
+            GST_WARNING_OBJECT(xvimagesink, "display mode[%d] set failed.", set_mode);
+          }
+        } else {
+          /* "xcontext" is not created yet. It will be applied when xcontext is created. */
+          GST_INFO_OBJECT(xvimagesink, "xcontext is NULL. display-mode will be set later.");
+          xvimagesink->config.display_mode = set_mode;
+        }
+      } else {
+        GST_INFO_OBJECT(xvimagesink, "skip display mode %d, because current mode is same", set_mode);
+      }
+
+      g_mutex_unlock(&xvimagesink->context->lock);
+      g_mutex_unlock(&xvimagesink->flow_lock);
+    }
+      break;
+    case PROP_DISPLAY_GEOMETRY_METHOD:
+      xvimagesink->display_geometry_method = g_value_get_enum (value);
+      GST_LOG("Overlay geometry changed. update it");
+      if (GST_STATE(xvimagesink) == GST_STATE_PAUSED) {
+        gst_xvimagesink_xvimage_put (xvimagesink, xvimagesink->cur_image);
+      }
+      break;
+    case PROP_FLIP:
+      xvimagesink->flip = g_value_get_enum(value);
+      break;
+    case PROP_ROTATE_ANGLE:
+      xvimagesink->rotate_angle = g_value_get_enum (value);
+      if (GST_STATE(xvimagesink) == GST_STATE_PAUSED) {
+        gst_xvimagesink_xvimage_put (xvimagesink, xvimagesink->cur_image);
+      }
+      break;
+    case PROP_VISIBLE:
+      g_mutex_lock( &xvimagesink->flow_lock );
+      g_mutex_lock( &xvimagesink->context->lock );
+
+      GST_WARNING_OBJECT(xvimagesink, "set visible %d", g_value_get_boolean(value));
+
+      if (xvimagesink->visible && (g_value_get_boolean(value) == FALSE)) {
+        if (xvimagesink->context) {
+#if 0
+          Atom atom_stream = XInternAtom( xvimagesink->context->disp,
+                                          "_USER_WM_PORT_ATTRIBUTE_STREAM_OFF", False );
+          if (atom_stream != None) {
+            GST_WARNING_OBJECT(xvimagesink, "Visible FALSE -> CALL STREAM_OFF");
+            if (XvSetPortAttribute(xvimagesink->context->disp,
+                                   xvimagesink->context->xv_port_id,
+                                   atom_stream, 0 ) != Success) {
+              GST_WARNING_OBJECT( xvimagesink, "Set visible FALSE failed" );
+            }
+          }
+#endif
+          xvimagesink->visible = g_value_get_boolean (value);
+          XvStopVideo(xvimagesink->context->disp, xvimagesink->context->xv_port_id, xvimagesink->xwindow->win);
+
+          XSync( xvimagesink->context->disp, FALSE );
+        } else {
+          GST_WARNING_OBJECT( xvimagesink, "xcontext is null");
+          xvimagesink->visible = g_value_get_boolean (value);
+        }
+
+      } else if (!xvimagesink->visible && (g_value_get_boolean(value) == TRUE)) {
+        g_mutex_unlock( &xvimagesink->context->lock );
+        g_mutex_unlock( &xvimagesink->flow_lock );
+        xvimagesink->visible = g_value_get_boolean (value);
+        gst_xvimagesink_xvimage_put (xvimagesink, xvimagesink->cur_image);
+        g_mutex_lock( &xvimagesink->flow_lock );
+        g_mutex_lock( &xvimagesink->context->lock );
+      }
+
+      GST_INFO("set visible(%d) done", xvimagesink->visible);
+
+      g_mutex_unlock( &xvimagesink->context->lock );
+      g_mutex_unlock( &xvimagesink->flow_lock );
+      break;
+    case PROP_ZOOM:
+      xvimagesink->zoom = g_value_get_float (value);
+      if (GST_STATE(xvimagesink) == GST_STATE_PAUSED) {
+        gst_xvimagesink_xvimage_put (xvimagesink, xvimagesink->cur_image);
+      }
+      break;
+    case PROP_ZOOM_POS_X:
+      xvimagesink->zoom_pos_x = g_value_get_int (value);
+      break;
+    case PROP_ZOOM_POS_Y:
+      xvimagesink->zoom_pos_y = g_value_get_int (value);
+      if (GST_STATE(xvimagesink) == GST_STATE_PAUSED) {
+        gst_xvimagesink_xvimage_put (xvimagesink, xvimagesink->cur_image);
+      }
+      break;
+    case PROP_ORIENTATION:
+      xvimagesink->orientation = g_value_get_enum (value);
+      GST_INFO("Orientation(%d) is changed", xvimagesink->orientation);
+      break;
+    case PROP_DST_ROI_MODE:
+      xvimagesink->dst_roi_mode = g_value_get_enum (value);
+      GST_INFO("Overlay geometry(%d) for ROI is changed", xvimagesink->dst_roi_mode);
+      break;
+    case PROP_DST_ROI_X:
+      xvimagesink->dst_roi.x = g_value_get_int (value);
+      break;
+    case PROP_DST_ROI_Y:
+      xvimagesink->dst_roi.y = g_value_get_int (value);
+      break;
+    case PROP_DST_ROI_W:
+      xvimagesink->dst_roi.w = g_value_get_int (value);
+      break;
+    case PROP_DST_ROI_H:
+      xvimagesink->dst_roi.h = g_value_get_int (value);
+      break;
+#endif /* GST_EXT_XV_ENHANCEMENT */
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -1719,6 +2632,50 @@ gst_xvimagesink_get_property (GObject * object, guint prop_id,
       else
         g_value_set_uint64 (value, 0);
       break;
+#ifdef GST_EXT_XV_ENHANCEMENT
+    case PROP_DISPLAY_MODE:
+      g_value_set_enum (value, xvimagesink->config.display_mode);
+      break;
+    case PROP_DISPLAY_GEOMETRY_METHOD:
+      g_value_set_enum (value, xvimagesink->display_geometry_method);
+      break;
+    case PROP_FLIP:
+      g_value_set_enum(value, xvimagesink->flip);
+      break;
+    case PROP_ROTATE_ANGLE:
+      g_value_set_enum (value, xvimagesink->rotate_angle);
+      break;
+    case PROP_VISIBLE:
+      g_value_set_boolean (value, xvimagesink->visible);
+      break;
+    case PROP_ZOOM:
+      g_value_set_float (value, xvimagesink->zoom);
+      break;
+    case PROP_ZOOM_POS_X:
+      g_value_set_int (value, xvimagesink->zoom_pos_x);
+      break;
+    case PROP_ZOOM_POS_Y:
+      g_value_set_int (value, xvimagesink->zoom_pos_y);
+      break;
+    case PROP_ORIENTATION:
+      g_value_set_enum (value, xvimagesink->orientation);
+      break;
+    case PROP_DST_ROI_MODE:
+      g_value_set_enum (value, xvimagesink->dst_roi_mode);
+      break;
+    case PROP_DST_ROI_X:
+      g_value_set_int (value, xvimagesink->dst_roi.x);
+      break;
+    case PROP_DST_ROI_Y:
+      g_value_set_int (value, xvimagesink->dst_roi.y);
+      break;
+    case PROP_DST_ROI_W:
+      g_value_set_int (value, xvimagesink->dst_roi.w);
+      break;
+    case PROP_DST_ROI_H:
+      g_value_set_int (value, xvimagesink->dst_roi.h);
+      break;
+#endif /* GST_EXT_XV_ENHANCEMENT */
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -1856,6 +2813,9 @@ gst_xvimagesink_init (GstXvImageSink * xvimagesink)
   xvimagesink->config.hue = xvimagesink->config.saturation = 0;
   xvimagesink->config.contrast = xvimagesink->config.brightness = 0;
   xvimagesink->config.cb_changed = FALSE;
+#ifdef GST_EXT_XV_ENHANCEMENT
+  xvimagesink->config.display_mode = DISPLAY_MODE_DEFAULT;
+#endif /* GST_EXT_XV_ENHANCEMENT */
 
   xvimagesink->context = NULL;
   xvimagesink->xwindow = NULL;
@@ -1878,6 +2838,25 @@ gst_xvimagesink_init (GstXvImageSink * xvimagesink)
   xvimagesink->handle_expose = TRUE;
 
   xvimagesink->draw_borders = TRUE;
+#ifdef GST_EXT_XV_ENHANCEMENT
+  xvimagesink->xid_updated = FALSE;
+  xvimagesink->display_geometry_method = DEF_DISPLAY_GEOMETRY_METHOD;
+  xvimagesink->flip = DEF_DISPLAY_FLIP;
+  xvimagesink->rotate_angle = DEGREE_270;
+  xvimagesink->visible = TRUE;
+  xvimagesink->zoom = 1.0;
+  xvimagesink->zoom_pos_x = -1;
+  xvimagesink->zoom_pos_y = -1;
+  xvimagesink->dst_roi_mode = DEF_ROI_DISPLAY_GEOMETRY_METHOD;
+  xvimagesink->orientation = DEGREE_0;
+  xvimagesink->dst_roi.x = 0;
+  xvimagesink->dst_roi.y = 0;
+  xvimagesink->dst_roi.w = 0;
+  xvimagesink->dst_roi.h = 0;
+
+  xvimagesink->is_zero_copy_format = FALSE;
+  xvimagesink->is_secure_path = FALSE;
+#endif /* GST_EXT_XV_ENHANCEMENT */
 }
 
 static void
@@ -2011,6 +2990,154 @@ gst_xvimagesink_class_init (GstXvImageSinkClass * klass)
           "Height of the window", 0, G_MAXUINT64, 0,
           G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
 
+#ifdef GST_EXT_XV_ENHANCEMENT
+  /**
+   * GstXvImageSink:display-mode
+   *
+   * select display mode
+   */
+  g_object_class_install_property(gobject_class, PROP_DISPLAY_MODE,
+    g_param_spec_enum("display-mode", "Display Mode",
+      "Display device setting",
+      GST_TYPE_XVIMAGESINK_DISPLAY_MODE, DISPLAY_MODE_DEFAULT,
+      G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
+  /**
+   * GstXvImageSink: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_XVIMAGESINK_DISPLAY_GEOMETRY_METHOD, DEF_DISPLAY_GEOMETRY_METHOD,
+      G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
+  /**
+   * GstXvImageSink:display-flip
+   *
+   * Display flip setting
+   */
+  g_object_class_install_property(gobject_class, PROP_FLIP,
+    g_param_spec_enum("flip", "Display flip",
+      "Flip for display",
+      GST_TYPE_XVIMAGESINK_FLIP, DEF_DISPLAY_FLIP,
+      G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
+  /**
+   * GstXvImageSink:rotate
+   *
+   * Draw rotation angle setting
+   */
+  g_object_class_install_property(gobject_class, PROP_ROTATE_ANGLE,
+    g_param_spec_enum("rotate", "Rotate angle",
+      "Rotate angle of display output",
+      GST_TYPE_XVIMAGESINK_ROTATE_ANGLE, DEGREE_270,
+      G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
+  /**
+   * GstXvImageSink:visible
+   *
+   * Whether reserve original src size or not
+   */
+  g_object_class_install_property (gobject_class, PROP_VISIBLE,
+      g_param_spec_boolean ("visible", "Visible",
+          "Draws screen or blacks out, true means visible, false blacks out",
+          TRUE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
+  /**
+   * GstXvImageSink:zoom
+   *
+   * Scale small area of screen to 1X~ 9
+   */
+  g_object_class_install_property (gobject_class, PROP_ZOOM,
+      g_param_spec_float ("zoom", "Zoom",
+          "Zooms screen as nX", 1.0, 9.0, 1.0,
+          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
+  /**
+   * GstXvImageSink:zoom-pos-x
+   *
+   * Standard x-position of zoom
+   */
+  g_object_class_install_property (gobject_class, PROP_ZOOM_POS_X,
+      g_param_spec_int ("zoom-pos-x", "Zoom Position X",
+          "Standard x-position of zoom", 0, 3840, 0,
+          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
+  /**
+   * GstXvImageSink:zoom-pos-y
+   *
+   * Standard y-position of zoom
+   */
+  g_object_class_install_property (gobject_class, PROP_ZOOM_POS_Y,
+      g_param_spec_int ("zoom-pos-y", "Zoom Position Y",
+          "Standard y-position of zoom", 0, 3840, 0,
+          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
+  /**
+   * GstXvImageSink:dst-roi-mode
+   *
+   * Display geometrical method of ROI setting
+   */
+  g_object_class_install_property(gobject_class, PROP_DST_ROI_MODE,
+    g_param_spec_enum("dst-roi-mode", "Display geometry method of ROI",
+      "Geometrical method of ROI for display",
+      GST_TYPE_XVIMAGESINK_ROI_DISPLAY_GEOMETRY_METHOD, DEF_ROI_DISPLAY_GEOMETRY_METHOD,
+      G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
+  /**
+   * GstXvImageSink:orientation
+   *
+   * Orientation information which will be used for ROI/ZOOM
+   */
+  g_object_class_install_property(gobject_class, PROP_ORIENTATION,
+    g_param_spec_enum("orientation", "Orientation information used for ROI/ZOOM",
+      "Orientation information for display",
+      GST_TYPE_XVIMAGESINK_ROTATE_ANGLE, DEGREE_0,
+      G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
+  /**
+   * GstXvImageSink: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));
+
+  /**
+   * GstXvImageSink: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));
+
+  /**
+   * GstXvImageSink: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));
+
+  /**
+   * GstXvImageSink: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));
+#endif /* GST_EXT_XV_ENHANCEMENT */
+
   gobject_class->finalize = gst_xvimagesink_finalize;
 
   gst_element_class_set_static_metadata (gstelement_class,
index aefb667..a6c48c3 100644 (file)
@@ -1,5 +1,6 @@
 /* GStreamer
  * Copyright (C) <2005> Julien Moutte <julien@moutte.net>
+ * Copyright (C) 2012, 2013 Samsung Electronics Co., Ltd.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
  * License along with this library; if not, write to the
  * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
  * Boston, MA 02110-1301, USA.
+ *
+ * Modifications by Samsung Electronics Co., Ltd.
+ * 1. Add display related properties
+ * 2. Support samsung extension format to improve performance
+ * 3. Support video texture overlay of OSP layer
  */
 
 #ifndef __GST_XVIMAGESINK_H__
@@ -37,6 +43,11 @@ G_BEGIN_DECLS
 #define GST_IS_XVIMAGESINK_CLASS(klass) \
   (G_TYPE_CHECK_CLASS_TYPE((klass), GST_TYPE_XVIMAGESINK))
 
+#ifdef GST_EXT_XV_ENHANCEMENT
+#define XV_SCREEN_SIZE_WIDTH 4096
+#define XV_SCREEN_SIZE_HEIGHT 4096
+#endif /* GST_EXT_XV_ENHANCEMENT */
+
 typedef struct _GstXvImageSink GstXvImageSink;
 typedef struct _GstXvImageSinkClass GstXvImageSinkClass;
 
@@ -120,6 +131,25 @@ struct _GstXvImageSink
 
   /* stream metadata */
   gchar *media_title;
+#ifdef GST_EXT_XV_ENHANCEMENT
+  gboolean xid_updated;
+  guint display_geometry_method;
+  guint flip;
+  guint rotate_angle;
+  gboolean visible;
+  gfloat zoom;
+  guint zoom_pos_x;
+  guint zoom_pos_y;
+  guint orientation;
+  guint dst_roi_mode;
+  GstVideoRectangle dst_roi;
+
+  /* zero copy format */
+  gboolean is_zero_copy_format;
+
+  /* secure contents path */
+  gboolean is_secure_path;
+#endif /* GST_EXT_XV_ENHANCEMENT */
 };
 
 struct _GstXvImageSinkClass