-Support of Samsung extention video formats ITLV, SN12, ST12.
-Support video texture overlay of OSP layer.
-Interface for camera control.
Change-Id: Ice02ca01e1b555036c1a80ea1bdea0f0df9bb218
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
#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)
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",
CLEANFILES = $(BUILT_SOURCES)
libgstvideo_@GST_API_VERSION@_la_SOURCES = \
+ cameracontrol.c \
+ cameracontrolchannel.c \
colorbalance.c \
colorbalancechannel.c \
navigation.c \
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 \
--- /dev/null
+/*
+ * 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);
+}
--- /dev/null
+/*
+ * 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__ */
--- /dev/null
+/* 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);
+ }
+}
--- /dev/null
+/* 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__ */
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,
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),
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'):
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'):
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,
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,
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);
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];
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.
*
GstBin *bin;
GstPad *pad;
GstElement *head = NULL, *prev = NULL, *elem = NULL;
+ GstPlugin *p;
chain = g_new0 (GstPlayVideoChain, 1);
chain->chain.playsink = playsink;
&& (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) {
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");
}
}
+#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 ***/
"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,
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
#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,
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,
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);
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,
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);
"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,
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",
"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,
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,
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,
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,
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,
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);
* 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
* 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
*/
/**
};
#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",
+* 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
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
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
# 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\
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
--- /dev/null
+/**************************************************************************
+
+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
+
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)
{
{
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;
}
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
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);
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 */
}
/* 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)
{
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);
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. */
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);
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);
/* 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;
window->render_rect.w = attr.width;
window->render_rect.h = attr.height;
}
+#endif /* GST_EXT_XV_ENHANCEMENT */
g_mutex_unlock (&context->lock);
}
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);
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(¤t_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 */
gint hue;
gint saturation;
gboolean cb_changed;
+
+#ifdef GST_EXT_XV_ENHANCEMENT
+ /* display mode */
+ guint display_mode;
+#endif /* GST_EXT_XV_ENHANCEMENT */
};
/**
#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
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);
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__ */
/* 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>
gint im_format;
GstVideoRectangle crop;
+#ifdef GST_EXT_XV_ENHANCEMENT
+ GstBuffer *current_buffer;
+#endif /* GST_EXT_XV_ENHANCEMENT */
+
XvImage *xvimage;
#ifdef HAVE_XSHM
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;
{
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;
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 */
{
}
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 */
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
/* 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>
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;
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 */
};
/* ============================================================= */
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;
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);
} else {
memcpy (&result, &xwindow->render_rect, sizeof (GstVideoRectangle));
}
+#endif /* GST_EXT_XV_ENHANCEMENT */
gst_xvimage_memory_render (mem, &src, xwindow, &result, draw_border);
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);
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
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;
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]) {
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);
}
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;
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;
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;
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);
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 {
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;
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)
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), ¤t_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);
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
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;
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;
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;
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
"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,
/* 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__
#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;
/* 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