SUBDIRS += evasimagesink
endif
-#if GST_TIZEN_USE_EVASPIXMAPSINK
-#SUBDIRS += evaspixmapsink
-#endif
-
if GST_TIZEN_USE_XVIMAGESRC
SUBDIRS += xvimagesrc
endif
SUBDIRS += tizenipc
endif
-#if GST_TIZEN_USE_WAYLANDSINK
-#SUBDIRS += waylandsink
-#endif
-
DIST_SUBDIRS = common
if GST_TIZEN_USE_ENCODEBIN
DIST_SUBDIRS += drmdecryptor
endif
-if GST_TIZEN_USE_WAYLANDSINK
-DIST_SUBDIRS += waylandsink
-endif
-
EXTRA_DIST = \
gstreamer.spec gstreamer.spec.in \
configure.ac autogen.sh depcomp \
PKG_CHECK_MODULES(MMCOMMON,mm-common)
AC_SUBST(MMCOMMON_CFLAGS)
-dnl required package for evasimagesink/evaspixmapsink
+dnl required package for evasimagesink
PKG_CHECK_MODULES(EFL, [
evas >= $EFL_REQUIRED
ecore >= $EFL_REQUIRED
])
])
-dnl *** belows are related to evaspixmapsink plug-ins ***
+dnl belows are related to wfdtsdemux
AG_GST_ARG_WITH_PACKAGE_NAME
AG_GST_ARG_WITH_PACKAGE_ORIGIN
AC_DEFINE_UNQUOTED(GST_LICENSE, "$GST_LICENSE", [GStreamer license])
AC_SUBST(GST_LICENSE)
-echo
-AC_MSG_NOTICE([Checking libraries for evaspixmapsink plugin])
-echo
-dnl *** X11 ***
-translit(dnm, m, l) AM_CONDITIONAL(USE_X, true)
-AG_GST_CHECK_FEATURE(X, [X libraries and plugins],
- [evaspixmapsink], [
- AC_PATH_XTRA
- ac_cflags_save="$CFLAGS"
- ac_cppflags_save="$CPPFLAGS"
- CFLAGS="$CFLAGS $X_CFLAGS"
- CPPFLAGS="$CPPFLAGS $X_CFLAGS"
-
- dnl now try to find the HEADER
- AC_CHECK_HEADER(X11/Xlib.h, HAVE_X="yes", HAVE_X="no")
-
- if test "x$HAVE_X" = "xno"
- then
- AC_MSG_NOTICE([cannot find X11 development files])
- else
- dnl this is much more than we want
- X_LIBS="$X_LIBS $X_PRE_LIBS $X_EXTRA_LIBS"
- dnl AC_PATH_XTRA only defines the path needed to find the X libs,
- dnl it does not add the libs; therefore we add them here
- X_LIBS="$X_LIBS -lX11"
- AC_SUBST(X_CFLAGS)
- AC_SUBST(X_LIBS)
-
- dnl xvimagesrc _CFLAGS and _LIB available
-
- PKG_CHECK_MODULES(DRI2, libdri2)
- AC_SUBST(DRI2_CFLAGS)
- AC_SUBST(DRI2_LIBS)
-
- PKG_CHECK_MODULES(X11, x11)
- AC_SUBST(X11_CFLAGS)
- AC_SUBST(X11_LIBS)
-
- PKG_CHECK_MODULES(XEXT, xext)
- AC_SUBST(XEXT_CFLAGS)
- AC_SUBST(XEXT_LIBS)
-
- PKG_CHECK_MODULES(XV, xv)
- AC_SUBST(XV_CFLAGS)
- AC_SUBST(XV_LIBS)
-
- PKG_CHECK_MODULES(XDAMAGE, xdamage)
- AC_SUBST(XDAMAGE_CFLAGS)
- AC_SUBST(XDAMAGE_LIBS)
-
- PKG_CHECK_MODULES(ECORE_X, ecore-x)
- AC_SUBST(ECORE_X_CFLAGS)
- AC_SUBST(ECORE_X_LIBS)
-
- fi
- AC_SUBST(HAVE_X)
- CFLAGS="$ac_cflags_save"
- CPPFLAGS="$ac_cppflags_save"
-])
-
-dnl Check for Xv extension
-translit(dnm, m, l) AM_CONDITIONAL(USE_XVIDEO, true)
-AG_GST_CHECK_FEATURE(XVIDEO, [X11 XVideo extensions],
- [evaspixmapsink], [
-AG_GST_CHECK_XV
-])
-
-dnl check for X Shm
-translit(dnm, m, l) AM_CONDITIONAL(USE_XSHM, true)
-AG_GST_CHECK_FEATURE(XSHM, [X Shared Memory extension], , [
- if test x$HAVE_X = xyes; then
- AC_CHECK_LIB(Xext, XShmAttach,
- HAVE_XSHM="yes", HAVE_XSHM="no",
- $X_LIBS)
- if test "x$HAVE_XSHM" = "xyes"; then
- XSHM_LIBS="-lXext"
- else
- dnl On AIX, it is in XextSam instead, but we still need -lXext
- AC_CHECK_LIB(XextSam, XShmAttach,
- HAVE_XSHM="yes", HAVE_XSHM="no",
- $X_LIBS)
- if test "x$HAVE_XSHM" = "xyes"; then
- XSHM_LIBS="-lXext -lXextSam"
- fi
- fi
- fi
-], , [
- AC_SUBST(HAVE_XSHM)
- AC_SUBST(XSHM_LIBS)
-])
-
dnl PKG_CHECK_MODULES(UDEVMGR, unified-dev-mgr)
dnl AC_SUBST(UDEVMGR_CFLAGS)
dnl AC_SUBST(UDEVMGR_LIBS)
[GST_TIZEN_USE_EVASIMAGESINK=yes])
AM_CONDITIONAL(GST_TIZEN_USE_EVASIMAGESINK, test "x$GST_TIZEN_USE_EVASIMAGESINK" = "xyes")
-dnl use evaspixmapsink ---------------------------------------------------------------------------
-AC_ARG_ENABLE(evaspixmapsink, AC_HELP_STRING([--enable-evaspixmapsink], [using evaspixmapsink]),
- [
- case "${enableval}" in
- yes) GST_TIZEN_USE_EVASPIXMAPSINK=yes ;;
- no) GST_TIZEN_USE_EVASPIXMAPSINK=no ;;
- *) AC_MSG_ERROR(bad value ${enableval} for --enable-evaspixmapsink) ;;
- esac
- ],
- [GST_TIZEN_USE_EVASPIXMAPSINK=yes])
-AM_CONDITIONAL(GST_TIZEN_USE_EVASPIXMAPSINK, test "x$GST_TIZEN_USE_EVASPIXMAPSINK" = "xyes")
-
dnl use xvimagesrc--------------------------------------------------------------------------
AC_ARG_ENABLE(xvimagesrc, AC_HELP_STRING([--enable-xvimagesrc], [using xvimagesrc]),
[
[GST_TIZEN_USE_DRMDECRYPTOR=yes])
AM_CONDITIONAL(GST_TIZEN_USE_DRMDECRYPTOR, test "x$GST_TIZEN_USE_DRMDECRYPTOR" = "xyes")
-dnl use waylandsink --------------------------------------------------------------------------
-AC_ARG_ENABLE(waylandsink, AC_HELP_STRING([--enable-waylandsink], [using waylandsink]),
-[
- case "${enableval}" in
- yes) GST_TIZEN_USE_WAYLANDSINK=yes ;;
- no) GST_TIZEN_USE_WAYLANDSINK=no ;;
- *) AC_MSG_ERROR(bad value ${enableval} for --enable-waylandsink) ;;
- esac
- ],
- [GST_TIZEN_USE_WAYLANDSINK=yes])
-AM_CONDITIONAL([GST_TIZEN_USE_WAYLANDSINK], [test "x$GST_TIZEN_USE_WAYLANDSINK" = "xyes"])
-if test "x$GST_TIZEN_USE_WAYLANDSINK" = "xyes"; then
-PKG_CHECK_MODULES(GST_WAYLAND, gstreamer-wayland-1.0 >= 1.2.0)
-AC_SUBST(GST_WAYLAND_CFLAGS)
-AC_SUBST(GST_WAYLAND_LIBS)
-
-PKG_CHECK_MODULES(WAYLAND, wayland-client >= 1.4.0 wayland-tbm-client tizen-extension-client wayland-scanner)
-AC_PATH_PROG([wayland_scanner], [wayland-scanner])
-fi
-
dnl use tizenipc--------------------------------------------------------------------------
AC_ARG_ENABLE(tizenipc, AC_HELP_STRING([--enable-tizenipc], [using tizenipc]),
[
encodebin/src/Makefile
evasimagesink/Makefile
evasimagesink/src/Makefile
-evaspixmapsink/Makefile
xvimagesrc/Makefile
xvimagesrc/src/Makefile
toggle/Makefile
waylandsrc/src/Makefile
drmdecryptor/Makefile
drmdecryptor/src/Makefile
-waylandsink/Makefile
-waylandsink/src/Makefile
tizenipc/Makefile
tizenipc/src/Makefile
)
+++ /dev/null
-plugin_LTLIBRARIES = libgstevaspixmapsink.la
-
-libgstevaspixmapsink_la_SOURCES = evaspixmapsink.c
-libgstevaspixmapsink_la_CFLAGS = $(GST_CFLAGS) $(X_CFLAGS) $(EFL_CFLAGS) \
- $(XFIXES_CFLAGS) $(DRI2PROTO_CFLAGS) $(DRI2_CFLAGS) $(X11_CFLAGS) $(XDAMAGE_CFLAGS) $(XV_CFLAGS)
-libgstevaspixmapsink_la_LIBADD = \
- $(GST_LIBS) -lgstvideo-$(GST_MAJORMINOR) \
- $(X_LIBS) $(XVIDEO_LIBS) $(XSHM_LIBS) $(LIBM) \
- $(EFL_LIBS) \
- $(XFIXES_LIBS) $(DRI2PROTO_LIBS) $(DRI2_LIBS) $(X11_LIBS) $(XDAMAGE_LIBS) $(XV_LIBS)
-libgstevaspixmapsink_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
-libgstxvimagesink_la_LIBTOOLFLAGS = --tag=disable-static
-
-noinst_HEADERS = evaspixmapsink.h
+++ /dev/null
-/*
- * EvasPixmapSink
- *
- * Copyright (c) 2000 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
- *
- * Contact: Sangchul Lee <sc11.lee@samsung.com>
- *
- * This library is free software; you can redistribute it and/or modify it under
- * the terms of the GNU Lesser General Public License as published by the
- * Free Software Foundation; either version 2.1 of the License, or (at your option)
- * any later version.
- *
- * This library is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
- * License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this library; if not, write to the Free Software Foundation, Inc., 51
- * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-/* Our interfaces */
-#include <gst/video/navigation.h>
-#include <gst/video/colorbalance.h>
-//#include <gst/video/propertyprobe.h>
-#include <gst/video/gstvideosink.h>
-/* Helper functions */
-#include <gst/video/video.h>
-
-/* Object header */
-#include "evaspixmapsink.h"
-
-#ifdef GST_EXT_XV_ENHANCEMENT
-/* Samsung extension headers */
-/* For xv extension header for buffer transfer (output) */
-#include "xv_types.h"
-
-/* headers for drm */
-#include <sys/stat.h>
-#include <sys/ioctl.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <X11/Xmd.h>
-#include <dri2/dri2.h>
-#include <libdrm/drm.h>
-
-//#define DUMP_IMG
-#ifdef DUMP_IMG
-#include <stdio.h>
-#endif
-typedef enum {
- BUF_SHARE_METHOD_PADDR = 0,
- BUF_SHARE_METHOD_FD
-} buf_share_method_t;
-
-/* max channel count *********************************************************/
-#define SCMN_IMGB_MAX_PLANE (4)
-
-/* image buffer definition ***************************************************
-
- +------------------------------------------+ ---
- | | ^
- | a[], p[] | |
- | +---------------------------+ --- | |
- | | | ^ | |
- | |<---------- w[] ---------->| | | |
- | | | | | |
- | | | |
- | | | h[] | e[]
- | | | |
- | | | | | |
- | | | | | |
- | | | v | |
- | +---------------------------+ --- | |
- | | v
- +------------------------------------------+ ---
-
- |<----------------- s[] ------------------>|
-*/
-
-typedef struct
-{
- /* width of each image plane */
- int w[SCMN_IMGB_MAX_PLANE];
- /* height of each image plane */
- int h[SCMN_IMGB_MAX_PLANE];
- /* stride of each image plane */
- int s[SCMN_IMGB_MAX_PLANE];
- /* elevation of each image plane */
- int e[SCMN_IMGB_MAX_PLANE];
- /* user space address of each image plane */
- void * a[SCMN_IMGB_MAX_PLANE];
- /* physical address of each image plane, if needs */
- void * p[SCMN_IMGB_MAX_PLANE];
- /* color space type of image */
- int cs;
- /* left postion, if needs */
- int x;
- /* top position, if needs */
- int y;
- /* to align memory */
- int __dummy2;
- /* arbitrary data */
- int data[16];
- /* dma buf fd */
- int dma_buf_fd[SCMN_IMGB_MAX_PLANE];
- /* buffer share method */
- int buf_share_method;
-} SCMN_IMGB;
-#endif
-
-/* Debugging category */
-#include <gst/gstinfo.h>
-GST_DEBUG_CATEGORY_STATIC (gst_debug_evaspixmapsink);
-#define GST_CAT_DEFAULT gst_debug_evaspixmapsink
-GST_DEBUG_CATEGORY_STATIC (GST_CAT_PERFORMANCE);
-
-#ifdef GST_EXT_XV_ENHANCEMENT
-
-enum {
- DEGREE_0,
- DEGREE_90,
- DEGREE_180,
- DEGREE_270,
- DEGREE_NUM,
-};
-
-enum {
- DISP_GEO_METHOD_LETTER_BOX = 0,
- DISP_GEO_METHOD_ORIGIN_SIZE,
- DISP_GEO_METHOD_FULL_SCREEN,
- DISP_GEO_METHOD_CROPPED_FULL_SCREEN,
- DISP_GEO_METHOD_CUSTOM_ROI,
- DISP_GEO_METHOD_NUM,
-};
-
-#define DEF_DISPLAY_GEOMETRY_METHOD DISP_GEO_METHOD_LETTER_BOX
-
-#define GST_TYPE_EVASPIXMAPSINK_DISPLAY_GEOMETRY_METHOD (gst_evaspixmapsink_display_geometry_method_get_type())
-
-static GType
-gst_evaspixmapsink_display_geometry_method_get_type(void)
-{
- static GType evaspixmapsink_display_geometry_method_type = 0;
- static const GEnumValue display_geometry_method_type[] = {
- { 0, "Letter box", "LETTER_BOX"},
- { 1, "Origin size", "ORIGIN_SIZE"},
- { 2, "Full-screen", "FULL_SCREEN"},
- { 3, "Cropped Full-screen", "CROPPED_FULL_SCREEN"},
- { 4, "Explicitely described destination ROI", "CUSTOM_ROI"},
- { 5, NULL, NULL},
- };
-
- if (!evaspixmapsink_display_geometry_method_type) {
- evaspixmapsink_display_geometry_method_type = g_enum_register_static("GstEvasPixmapSinkDisplayGeometryMethodType", display_geometry_method_type);
- }
-
- return evaspixmapsink_display_geometry_method_type;
-}
-#endif /* GST_EXT_XV_ENHANCEMENT */
-
-typedef struct
-{
- unsigned long flags;
- unsigned long functions;
- unsigned long decorations;
- long input_mode;
- unsigned long status;
-}
-MotifWmHints, MwmHints;
-
-#define MWM_HINTS_DECORATIONS (1L << 1)
-
-static void gst_evaspixmapsink_reset (GstEvasPixmapSink *evaspixmapsink);
-static void gst_evaspixmap_buffer_finalize (GstEvasPixmapBuffer *evaspixmapbuf);
-static void gst_evaspixmapsink_navigation_init (GstNavigationInterface *iface);
-static void gst_evaspixmapsink_colorbalance_init (GstColorBalanceInterface *iface);
-static void gst_evaspixmapsink_property_probe_interface_init (GstPropertyProbeInterface *iface);
-static void gst_evaspixmapsink_xcontext_clear (GstEvasPixmapSink *evaspixmapsink);
-static void gst_evaspixmapsink_xpixmap_destroy (GstEvasPixmapSink *evaspixmapsink, GstXPixmap *xpixmap);
-static void gst_evaspixmapsink_xpixmap_update_geometry (GstEvasPixmapSink *evaspixmapsink);
-static gboolean gst_evaspixmap_buffer_put (GstEvasPixmapSink *evaspixmapsink, GstEvasPixmapBuffer *evaspixmapbuf);
-static gboolean gst_evaspixmapsink_xpixmap_link (GstEvasPixmapSink *evaspixmapsink);
-static void gst_evaspixmapsink_xpixmap_clear (GstEvasPixmapSink *evaspixmapsink, GstXPixmap *xpixmap);
-static gint gst_evaspixmapsink_get_format_from_caps (GstEvasPixmapSink *evaspixmapsink, GstCaps *caps);
-static void drm_close_gem(GstEvasPixmapSink *evaspixmapsink, unsigned int gem_handle);
-#ifdef DUMP_IMG
-int util_write_rawdata (const char *file, const void *data, unsigned int size);
-int g_cnt = 0;
-#endif
-/* Default template - initiated with class struct to allow gst-register to work
- without X running */
-static GstStaticPadTemplate gst_evaspixmapsink_sink_template_factory =
- GST_STATIC_PAD_TEMPLATE ("sink",
- GST_PAD_SINK,
- GST_PAD_ALWAYS,
- GST_STATIC_CAPS ("video/x-raw, "
- "framerate = (fraction) [ 0, MAX ], "
- "width = (int) [ 1, MAX ], " "height = (int) [ 1, MAX ]")
- );
-
-enum
-{
- PROP_0,
- PROP_CONTRAST,
- PROP_BRIGHTNESS,
- PROP_HUE,
- PROP_SATURATION,
- PROP_DISPLAY,
- PROP_SYNCHRONOUS,
- PROP_PIXEL_ASPECT_RATIO,
- PROP_FORCE_ASPECT_RATIO,
- PROP_DEVICE,
- PROP_DEVICE_NAME,
- PROP_DOUBLE_BUFFER,
- PROP_AUTOPAINT_COLORKEY,
- PROP_COLORKEY,
- PROP_PIXMAP_WIDTH,
- PROP_PIXMAP_HEIGHT,
-#ifdef GST_EXT_XV_ENHANCEMENT
- PROP_DISPLAY_GEOMETRY_METHOD,
- PROP_ZOOM,
- PROP_DST_ROI_X,
- PROP_DST_ROI_Y,
- PROP_DST_ROI_W,
- PROP_DST_ROI_H,
- PROP_STOP_VIDEO,
-#endif
- PROP_EVAS_OBJECT,
- PROP_VISIBLE,
- PROP_ORIGIN_SIZE,
-};
-
-#define gst_evaspixmapsink_parent_class parent_class
-
-/* ============================================================= */
-/* */
-/* Private Methods */
-/* */
-/* ============================================================= */
-
-/* evaspixmap buffers */
-
-#define GST_TYPE_EVASPIXMAP_BUFFER (gst_evaspixmap_buffer_get_type())
-
-#define GST_IS_EVASPIXMAP_BUFFER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_EVASPIXMAP_BUFFER))
-#define GST_EVASPIXMAP_BUFFER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_EVASPIXMAP_BUFFER, GstEvasPixmapBuffer))
-
-G_DEFINE_BOXED_TYPE(GstEvasPixmapBuffer, gst_evaspixmap_buffer, NULL, gst_evaspixmap_buffer_finalize);
-
-static void
-ecore_pipe_callback_handler (void *data, void *buffer, unsigned int nbyte)
-{
- GstEvasPixmapSink *evaspixmapsink = (GstEvasPixmapSink*)data;
- GST_DEBUG_OBJECT (evaspixmapsink,"[START]");
-
- if (!data ) {
- GST_WARNING_OBJECT (evaspixmapsink,"data is NULL..");
- return;
- }
- if (!evaspixmapsink->eo) {
- GST_WARNING_OBJECT (evaspixmapsink,"evas object is NULL..");
- return;
- }
-
- /* mapping evas object with xpixmap */
- if (evaspixmapsink->do_link) {
- GST_DEBUG_OBJECT (evaspixmapsink,"do link");
- if (evaspixmapsink->xpixmap->pixmap) {
- Evas_Native_Surface surf;
- surf.version = EVAS_NATIVE_SURFACE_VERSION;
- surf.type = EVAS_NATIVE_SURFACE_X11;
- surf.data.x11.visual = ecore_x_default_visual_get(ecore_x_display_get(), ecore_x_default_screen_get());
- surf.data.x11.pixmap = evaspixmapsink->xpixmap->pixmap;
- evas_object_image_native_surface_set(evaspixmapsink->eo, &surf);
- evaspixmapsink->do_link = FALSE;
- } else {
- GST_WARNING_OBJECT (evaspixmapsink,"pixmap is NULL..");
- return;
- }
- } else {
- GST_DEBUG_OBJECT (evaspixmapsink,"update");
- /* update evas image object size */
- if (evaspixmapsink->use_origin_size) {
- evas_object_geometry_get(evaspixmapsink->eo, NULL, NULL, &evaspixmapsink->w, &evaspixmapsink->h);
- }
- evas_object_image_pixels_dirty_set (evaspixmapsink->eo, 1);
- evas_object_image_fill_set(evaspixmapsink->eo, 0, 0, evaspixmapsink->w, evaspixmapsink->h);
- evas_object_image_data_update_add(evaspixmapsink->eo, 0, 0, evaspixmapsink->w, evaspixmapsink->h);
- }
-
- GST_DEBUG_OBJECT (evaspixmapsink,"[END]");
-}
-
-static void
-evas_callback_resize_event (void *data, Evas *e, Evas_Object *obj, void *event_info)
-{
- int w = 0;
- int h = 0;
- float former_ratio = 0;
- float ratio = 0;
- float abs_margin = 0;
-
- GstEvasPixmapSink *evaspixmapsink = (GstEvasPixmapSink *)data;
- GST_DEBUG_OBJECT (evaspixmapsink,"[START]");
-
- evas_object_geometry_get(evaspixmapsink->eo, NULL, NULL, &w, &h);
- GST_DEBUG_OBJECT (evaspixmapsink,"resized : w(%d), h(%d)", w, h);
- if (!evaspixmapsink->use_origin_size &&
- (evaspixmapsink->w != w || evaspixmapsink->h != h)) {
- former_ratio = (float)evaspixmapsink->w / evaspixmapsink->h;
- ratio = (float)w / h;
- evaspixmapsink->w = w;
- evaspixmapsink->h = h;
-
-#ifdef COMPARE_RATIO
- GST_DEBUG_OBJECT (evaspixmapsink,"resized : ratio(%.3f=>%.3f)", former_ratio, ratio);
- if ( former_ratio >= ratio ) {
- abs_margin = former_ratio - ratio;
- } else {
- abs_margin = ratio - former_ratio;
- }
- /* re-link_pixmap can only be set when ratio is changed */
- if ( abs_margin >= MARGIN_OF_ERROR ) {
-#endif
- if (!gst_evaspixmapsink_xpixmap_link(evaspixmapsink)) {
- GST_ERROR_OBJECT (evaspixmapsink,"link evas image object with pixmap failed...");
- return;
- }
-#ifdef COMPARE_RATIO
- }
-#endif
- }
-
- gst_evaspixmap_buffer_put (evaspixmapsink, evaspixmapsink->evas_pixmap_buf);
-
- GST_DEBUG_OBJECT (evaspixmapsink,"[END]");
-}
-
-static inline gboolean
-is_evas_image_object (Evas_Object *obj)
-{
- const char *type;
- if (!obj) {
- return FALSE;
- }
- type = evas_object_type_get (obj);
- if (!type) {
- return FALSE;
- }
- if (strcmp (type, "image") == 0) {
- return TRUE;
- }
- return FALSE;
-}
-
-static void
-evas_callback_del_event (void *data, Evas *e, Evas_Object *obj, void *event_info)
-{
- GstEvasPixmapSink *evaspixmapsink = data;
- if (!evaspixmapsink) {
- GST_WARNING ("evaspixmapsink is NULL..");
- return;
- }
- GST_DEBUG_OBJECT (evaspixmapsink,"[START]");
-
- evas_object_event_callback_del(evaspixmapsink->eo, EVAS_CALLBACK_RESIZE, evas_callback_resize_event);
- if (evaspixmapsink->eo) {
- evas_object_image_native_surface_set(evaspixmapsink->eo, NULL);
- evaspixmapsink->eo = NULL;
- }
-
- GST_DEBUG_OBJECT (evaspixmapsink,"[END]");
-}
-
-/* X11 stuff */
-static gboolean error_caught = FALSE;
-
-static int
-gst_evaspixmapsink_handle_xerror (Display * display, XErrorEvent * xevent)
-{
- char error_msg[1024];
-
- XGetErrorText (display, xevent->error_code, error_msg, 1024);
- GST_DEBUG ("evaspixmapsink triggered an XError. error: %s", error_msg);
- error_caught = TRUE;
- return 0;
-}
-
-#ifdef DUMP_IMG
-int util_write_rawdata(const char *file, const void *data, unsigned int size)
-{
- FILE *fp;
-
- fp = fopen(file, "wb");
- if (fp == NULL)
- {
- GST_WARNING("fopen fail... size : %d", size);
- return -1;
- }
- fwrite((char*)data, sizeof(char), size, fp);
- fclose(fp);
-
- return 0;
-}
-#endif
-
-#ifdef HAVE_XSHM
-/* This function checks that it is actually really possible to create an image
- using XShm */
-static gboolean
-gst_evaspixmapsink_check_xshm_calls (GstXContext * xcontext)
-{
- XvImage *xvimage;
- XShmSegmentInfo SHMInfo;
- gint size;
- int (*handler) (Display *, XErrorEvent *);
- gboolean result = FALSE;
- gboolean did_attach = FALSE;
-
- g_return_val_if_fail (xcontext != NULL, FALSE);
-
- /* Sync to ensure any older errors are already processed */
- XSync (xcontext->disp, FALSE);
-
- /* Set defaults so we don't free these later unnecessarily */
- SHMInfo.shmaddr = ((void *) -1);
- SHMInfo.shmid = -1;
-
- /* Setting an error handler to catch failure */
- error_caught = FALSE;
- handler = XSetErrorHandler (gst_evaspixmapsink_handle_xerror);
-
- /* Trying to create a 1x1 picture */
- GST_DEBUG ("XvShmCreateImage of 1x1");
- xvimage = XvShmCreateImage (xcontext->disp, xcontext->xv_port_id,
- xcontext->im_format, NULL, 1, 1, &SHMInfo);
-
- /* Might cause an error, sync to ensure it is noticed */
- XSync (xcontext->disp, FALSE);
- if (!xvimage || error_caught) {
- GST_WARNING ("could not XvShmCreateImage a 1x1 image");
- goto beach;
- }
- size = xvimage->data_size;
-
- SHMInfo.shmid = shmget (IPC_PRIVATE, size, IPC_CREAT | 0777);
- if (SHMInfo.shmid == -1) {
- GST_WARNING ("could not get shared memory of %d bytes", size);
- goto beach;
- }
-
- SHMInfo.shmaddr = shmat (SHMInfo.shmid, NULL, 0);
- if (SHMInfo.shmaddr == ((void *) -1)) {
- GST_WARNING ("Failed to shmat: %s", g_strerror (errno));
- /* Clean up the shared memory segment */
- shmctl (SHMInfo.shmid, IPC_RMID, NULL);
- goto beach;
- }
-
- xvimage->data = SHMInfo.shmaddr;
- SHMInfo.readOnly = FALSE;
-
- if (XShmAttach (xcontext->disp, &SHMInfo) == 0) {
- GST_WARNING ("Failed to XShmAttach");
- /* Clean up the shared memory segment */
- shmctl (SHMInfo.shmid, IPC_RMID, NULL);
- goto beach;
- }
-
- /* Sync to ensure we see any errors we caused */
- XSync (xcontext->disp, FALSE);
-
- /* Delete the shared memory segment as soon as everyone is attached.
- * This way, it will be deleted as soon as we detach later, and not
- * leaked if we crash. */
- shmctl (SHMInfo.shmid, IPC_RMID, NULL);
-
- if (!error_caught) {
- GST_DEBUG ("XServer ShmAttached to 0x%x, id 0x%lx", SHMInfo.shmid,
- SHMInfo.shmseg);
-
- did_attach = TRUE;
- /* store whether we succeeded in result */
- result = TRUE;
- } else {
- GST_WARNING ("MIT-SHM extension check failed at XShmAttach. "
- "Not using shared memory.");
- }
-
-beach:
- /* Sync to ensure we swallow any errors we caused and reset error_caught */
- XSync (xcontext->disp, FALSE);
-
- error_caught = FALSE;
- XSetErrorHandler (handler);
-
- if (did_attach) {
- GST_DEBUG ("XServer ShmDetaching from 0x%x id 0x%lx",
- SHMInfo.shmid, SHMInfo.shmseg);
- XShmDetach (xcontext->disp, &SHMInfo);
- XSync (xcontext->disp, FALSE);
- }
- if (SHMInfo.shmaddr != ((void *) -1))
- shmdt (SHMInfo.shmaddr);
- if (xvimage)
- XFree (xvimage);
- return result;
-}
-#endif /* HAVE_XSHM */
-
-/* This function destroys a GstEvasPixmap handling XShm availability */
-static void
-gst_evaspixmap_buffer_destroy (GstEvasPixmapBuffer *evaspixmapbuf)
-{
- GstEvasPixmapSink *evaspixmapsink;
-
- GST_DEBUG_OBJECT (evaspixmapsink,"Destroying buffer");
-
- evaspixmapsink = evaspixmapbuf->evaspixmapsink;
- if (G_UNLIKELY (evaspixmapsink == NULL)) {
- goto no_sink;
- }
-
- g_return_if_fail (GST_IS_EVASPIXMAPSINK (evaspixmapsink));
-
- GST_OBJECT_LOCK (evaspixmapsink);
-
- /* We might have some buffers destroyed after changing state to NULL */
- if (evaspixmapsink->xcontext == NULL) {
- GST_DEBUG_OBJECT (evaspixmapsink,"Destroying XvImage after Xcontext");
-#ifdef HAVE_XSHM
- /* Need to free the shared memory segment even if the x context
- * was already cleaned up */
- if (evaspixmapbuf->SHMInfo.shmaddr != ((void *) -1)) {
- shmdt (evaspixmapbuf->SHMInfo.shmaddr);
- }
-#endif
- goto beach;
- }
- g_mutex_lock (evaspixmapsink->x_lock);
-
-#ifdef HAVE_XSHM
- if (evaspixmapsink->xcontext->use_xshm) {
- if (evaspixmapbuf->SHMInfo.shmaddr != ((void *) -1)) {
- GST_DEBUG_OBJECT (evaspixmapsink,"XServer ShmDetaching from 0x%x id 0x%lx", evaspixmapbuf->SHMInfo.shmid, evaspixmapbuf->SHMInfo.shmseg);
- XShmDetach (evaspixmapsink->xcontext->disp, &evaspixmapbuf->SHMInfo);
- XSync (evaspixmapsink->xcontext->disp, FALSE);
- shmdt (evaspixmapbuf->SHMInfo.shmaddr);
- }
- if (evaspixmapbuf->xvimage)
- XFree (evaspixmapbuf->xvimage);
- } else
-#endif /* HAVE_XSHM */
- {
- if (evaspixmapbuf->xvimage) {
- if (evaspixmapbuf->xvimage->data) {
- g_free (evaspixmapbuf->xvimage->data);
- }
- XFree (evaspixmapbuf->xvimage);
- }
- }
-
- XSync (evaspixmapsink->xcontext->disp, FALSE);
-
- g_mutex_unlock (evaspixmapsink->x_lock);
-
-beach:
- GST_OBJECT_UNLOCK (evaspixmapsink);
- evaspixmapbuf->evaspixmapsink = NULL;
- gst_object_unref (evaspixmapsink);
- gst_buffer_unref(evaspixmapbuf->buffer);
- free(evaspixmapbuf);
- return;
-
- no_sink:
- {
- GST_WARNING_OBJECT (evaspixmapsink,"no sink found");
- return;
- }
-}
-
-static void
-gst_evaspixmap_buffer_finalize (GstEvasPixmapBuffer *evaspixmapbuf)
-{
- GstEvasPixmapSink *evaspixmapsink;
-
- evaspixmapsink = evaspixmapbuf->evaspixmapsink;
- if (G_UNLIKELY (evaspixmapsink == NULL)) {
- GST_WARNING_OBJECT (evaspixmapsink,"no sink found");
- return;
- }
- g_return_if_fail (GST_IS_EVASPIXMAPSINK (evaspixmapsink));
-
- /* If our geometry changed we can't reuse that image. */
- GST_LOG_OBJECT (evaspixmapsink,"destroy image as sink is shutting down");
- gst_evaspixmap_buffer_destroy (evaspixmapbuf);
-}
-
-static void
-gst_evaspixmap_buffer_free (GstEvasPixmapBuffer *evaspixmapbuf)
-{
- /* make sure it is not recycled */
- evaspixmapbuf->width = -1;
- evaspixmapbuf->height = -1;
- g_boxed_free(GST_TYPE_EVASPIXMAP_BUFFER, evaspixmapbuf);
-}
-
-static void
-gst_evaspixmap_buffer_init (GstEvasPixmapBuffer *evaspixmapbuf, gpointer g_class)
-{
-#ifdef HAVE_XSHM
- evaspixmapbuf->SHMInfo.shmaddr = ((void *) -1);
- evaspixmapbuf->SHMInfo.shmid = -1;
-#endif
-}
-
-static void
-gst_evaspixmap_buffer_class_init (gpointer g_class, gpointer class_data)
-{
-}
-
-/* This function handles GstEvasPixmapBuffer creation depending on XShm availability */
-static GstEvasPixmapBuffer*
-gst_evaspixmap_buffer_new (GstEvasPixmapSink *evaspixmapsink, GstCaps *caps)
-{
- GstEvasPixmapBuffer *evaspixmapbuf = NULL;
- GstStructure *structure = NULL;
- gboolean succeeded = FALSE;
- int (*handler) (Display *, XErrorEvent *);
-
- g_return_val_if_fail (GST_IS_EVASPIXMAPSINK (evaspixmapsink), NULL);
-
- if (caps == NULL) {
- return NULL;
- }
-
- evaspixmapbuf = (GstEvasPixmapBuffer*) malloc (sizeof(GstEvasPixmapBuffer));
- GST_DEBUG_OBJECT (evaspixmapsink,"Creating new EvasPixmapBuffer");
- evaspixmapbuf->buffer = gst_buffer_new();
-
- structure = gst_caps_get_structure (caps, 0);
-
- if (!gst_structure_get_int (structure, "width", &evaspixmapbuf->width) || !gst_structure_get_int (structure, "height", &evaspixmapbuf->height)) {
- GST_WARNING_OBJECT (evaspixmapsink,"failed getting geometry from caps %" GST_PTR_FORMAT, caps);
- }
-
- GST_LOG_OBJECT (evaspixmapsink,"creating %dx%d", evaspixmapbuf->width, evaspixmapbuf->height);
-#ifdef GST_EXT_XV_ENHANCEMENT
- GST_LOG_OBJECT (evaspixmapsink,"aligned size %dx%d", evaspixmapsink->aligned_width, evaspixmapsink->aligned_height);
- if (evaspixmapsink->aligned_width == 0 || evaspixmapsink->aligned_height == 0) {
- GST_INFO_OBJECT (evaspixmapsink,"aligned size is zero. set size of caps.");
- evaspixmapsink->aligned_width = evaspixmapbuf->width;
- evaspixmapsink->aligned_height = evaspixmapbuf->height;
- }
-#endif
-
- evaspixmapbuf->im_format = gst_evaspixmapsink_get_format_from_caps (evaspixmapsink, caps);
- if (evaspixmapbuf->im_format == -1) {
- GST_WARNING_OBJECT (evaspixmapsink,"failed to get format from caps %"GST_PTR_FORMAT, caps);
- GST_ELEMENT_ERROR (evaspixmapsink, RESOURCE, WRITE,("Failed to create output image buffer of %dx%d pixels",
- evaspixmapbuf->width, evaspixmapbuf->height), ("Invalid input caps"));
- goto beach_unlocked;
- }
- evaspixmapbuf->evaspixmapsink = gst_object_ref (evaspixmapsink);
-
- g_mutex_lock (evaspixmapsink->x_lock);
-
- /* Setting an error handler to catch failure */
- error_caught = FALSE;
- handler = XSetErrorHandler (gst_evaspixmapsink_handle_xerror);
-
-#ifdef HAVE_XSHM
- if (evaspixmapsink->xcontext->use_xshm) {
- int expected_size;
- evaspixmapbuf->xvimage = XvShmCreateImage (evaspixmapsink->xcontext->disp, evaspixmapsink->xcontext->xv_port_id, evaspixmapbuf->im_format, NULL,
-#ifdef GST_EXT_XV_ENHANCEMENT
- evaspixmapsink->aligned_width, evaspixmapsink->aligned_height, &evaspixmapbuf->SHMInfo);
- if(!evaspixmapbuf->xvimage) {
- GST_ERROR_OBJECT (evaspixmapsink,"XvShmCreateImage() failed");
- }
-#else
- evaspixmapbuf->width, evaspixmapbuf->height, &evaspixmapbuf->SHMInfo);
-#endif
- if (!evaspixmapbuf->xvimage || error_caught) {
- if (error_caught) {
- GST_ERROR_OBJECT (evaspixmapsink,"error_caught!");
- }
- g_mutex_unlock (evaspixmapsink->x_lock);
- /* Reset error handler */
- error_caught = FALSE;
- XSetErrorHandler (handler);
- /* Push an error */
- GST_ELEMENT_ERROR (evaspixmapsink, RESOURCE, WRITE,("Failed to create output image buffer of %dx%d pixels",evaspixmapbuf->width,
- evaspixmapbuf->height),("could not XvShmCreateImage a %dx%d image",evaspixmapbuf->width, evaspixmapbuf->height));
- goto beach_unlocked;
- }
-
- /* we have to use the returned data_size for our shm size */
- evaspixmapbuf->size = evaspixmapbuf->xvimage->data_size;
- GST_LOG_OBJECT (evaspixmapsink,"XShm image size is %" G_GSIZE_FORMAT, evaspixmapbuf->size);
-
- /* calculate the expected size. This is only for sanity checking the
- * number we get from X. */
- switch (evaspixmapbuf->im_format) {
- case GST_MAKE_FOURCC ('I', '4', '2', '0'):
- case GST_MAKE_FOURCC ('Y', 'V', '1', '2'):
- {
- gint pitches[3];
- gint offsets[3];
- guint plane;
-
- offsets[0] = 0;
- pitches[0] = GST_ROUND_UP_4 (evaspixmapbuf->width);
- offsets[1] = offsets[0] + pitches[0] * GST_ROUND_UP_2 (evaspixmapbuf->height);
- pitches[1] = GST_ROUND_UP_8 (evaspixmapbuf->width) / 2;
- offsets[2] =
- offsets[1] + pitches[1] * GST_ROUND_UP_2 (evaspixmapbuf->height) / 2;
- pitches[2] = GST_ROUND_UP_8 (pitches[0]) / 2;
-
- expected_size = offsets[2] + pitches[2] * GST_ROUND_UP_2 (evaspixmapbuf->height) / 2;
-
- for (plane = 0; plane < evaspixmapbuf->xvimage->num_planes; plane++) {
- GST_DEBUG_OBJECT (evaspixmapsink,"Plane %u has a expected pitch of %d bytes, " "offset of %d",
- plane, pitches[plane], offsets[plane]);
- }
- break;
- }
- case GST_MAKE_FOURCC ('Y', 'U', 'Y', '2'):
- case GST_MAKE_FOURCC ('U', 'Y', 'V', 'Y'):
- expected_size = evaspixmapbuf->height * GST_ROUND_UP_4 (evaspixmapbuf->width * 2);
- break;
-
- #ifdef GST_EXT_XV_ENHANCEMENT
- case GST_MAKE_FOURCC ('S', 'T', '1', '2'):
- case GST_MAKE_FOURCC ('S', 'N', '1', '2'):
- case GST_MAKE_FOURCC ('S', 'U', 'Y', 'V'):
- case GST_MAKE_FOURCC ('S', 'U', 'Y', '2'):
- case GST_MAKE_FOURCC ('S', '4', '2', '0'):
- case GST_MAKE_FOURCC ('S', 'Y', 'V', 'Y'):
- expected_size = sizeof(SCMN_IMGB);
- break;
- #endif
- default:
- expected_size = 0;
- break;
- }
- if (expected_size != 0 && evaspixmapbuf->size != expected_size) {
- GST_WARNING_OBJECT (evaspixmapsink,"unexpected XShm image size (got %" G_GSIZE_FORMAT ", expected %d)", evaspixmapbuf->size, expected_size);
- }
-
- /* Be verbose about our XvImage stride */
- {
- guint plane;
- for (plane = 0; plane < evaspixmapbuf->xvimage->num_planes; plane++) {
- GST_DEBUG_OBJECT (evaspixmapsink,"Plane %u has a pitch of %d bytes, ""offset of %d", plane,
- evaspixmapbuf->xvimage->pitches[plane], evaspixmapbuf->xvimage->offsets[plane]);
- }
- }
-
- evaspixmapbuf->SHMInfo.shmid = shmget (IPC_PRIVATE, evaspixmapbuf->size,IPC_CREAT | 0777);
- if (evaspixmapbuf->SHMInfo.shmid == -1) {
- g_mutex_unlock (evaspixmapsink->x_lock);
- GST_ELEMENT_ERROR (evaspixmapsink, RESOURCE, WRITE,
- ("Failed to create output image buffer of %dx%d pixels", evaspixmapbuf->width, evaspixmapbuf->height),
- ("could not get shared memory of %" G_GSIZE_FORMAT " bytes",evaspixmapbuf->size));
- goto beach_unlocked;
- }
-
- evaspixmapbuf->SHMInfo.shmaddr = shmat (evaspixmapbuf->SHMInfo.shmid, NULL, 0);
- if (evaspixmapbuf->SHMInfo.shmaddr == ((void *) -1)) {
- g_mutex_unlock (evaspixmapsink->x_lock);
- GST_ELEMENT_ERROR (evaspixmapsink, RESOURCE, WRITE,
- ("Failed to create output image buffer of %dx%d pixels",
- evaspixmapbuf->width, evaspixmapbuf->height),
- ("Failed to shmat: %s", g_strerror (errno)));
- /* Clean up the shared memory segment */
- shmctl (evaspixmapbuf->SHMInfo.shmid, IPC_RMID, NULL);
- goto beach_unlocked;
- }
-
- evaspixmapbuf->xvimage->data = evaspixmapbuf->SHMInfo.shmaddr;
- evaspixmapbuf->SHMInfo.readOnly = FALSE;
-
- if (XShmAttach (evaspixmapsink->xcontext->disp, &evaspixmapbuf->SHMInfo) == 0) {
- /* Clean up the shared memory segment */
- shmctl (evaspixmapbuf->SHMInfo.shmid, IPC_RMID, NULL);
-
- g_mutex_unlock (evaspixmapsink->x_lock);
- GST_ELEMENT_ERROR (evaspixmapsink, RESOURCE, WRITE,
- ("Failed to create output image buffer of %dx%d pixels",
- evaspixmapbuf->width, evaspixmapbuf->height), ("Failed to XShmAttach"));
- goto beach_unlocked;
- }
-
- XSync (evaspixmapsink->xcontext->disp, FALSE);
-
- /* Delete the shared memory segment as soon as we everyone is attached.
- * This way, it will be deleted as soon as we detach later, and not
- * leaked if we crash. */
- shmctl (evaspixmapbuf->SHMInfo.shmid, IPC_RMID, NULL);
-
- GST_DEBUG_OBJECT (evaspixmapsink,"XServer ShmAttached to 0x%x, id 0x%lx", evaspixmapbuf->SHMInfo.shmid, evaspixmapbuf->SHMInfo.shmseg);
- } else
-#endif /* HAVE_XSHM */
- {
- evaspixmapbuf->xvimage = XvCreateImage (evaspixmapsink->xcontext->disp, evaspixmapsink->xcontext->xv_port_id,
-#ifdef GST_EXT_XV_ENHANCEMENT
- evaspixmapbuf->im_format, NULL, evaspixmapsink->aligned_width, evaspixmapsink->aligned_height);
-#else
- evaspixmapbuf->im_format, NULL, evaspixmapbuf->width, evaspixmapbuf->height);
-#endif
- if (!evaspixmapbuf->xvimage || error_caught) {
- g_mutex_unlock (evaspixmapsink->x_lock);
- /* Reset error handler */
- error_caught = FALSE;
- XSetErrorHandler (handler);
- /* Push an error */
- GST_ELEMENT_ERROR (evaspixmapsink, RESOURCE, WRITE,
- ("Failed to create outputimage buffer of %dx%d pixels",
- evaspixmapbuf->width, evaspixmapbuf->height),
- ("could not XvCreateImage a %dx%d image",
- evaspixmapbuf->width, evaspixmapbuf->height));
- goto beach_unlocked;
- }
-
- /* we have to use the returned data_size for our image size */
- evaspixmapbuf->size = evaspixmapbuf->xvimage->data_size;
- evaspixmapbuf->xvimage->data = g_malloc (evaspixmapbuf->size);
-
- XSync (evaspixmapsink->xcontext->disp, FALSE);
- }
-
- /* Reset error handler */
- error_caught = FALSE;
- XSetErrorHandler (handler);
-
- succeeded = TRUE;
-
- gst_buffer_replace_all_memory(evaspixmapbuf->buffer, gst_memory_new_wrapped(GST_MEMORY_FLAG_READONLY,
- (guchar *) evaspixmapbuf->xvimage->data,
- evaspixmapbuf->size,
- 0,
- evaspixmapbuf->size,
- NULL, NULL));
- g_mutex_unlock (evaspixmapsink->x_lock);
-
-beach_unlocked:
- if (!succeeded) {
- gst_evaspixmap_buffer_free (evaspixmapbuf);
- evaspixmapbuf = NULL;
- }
-
- return evaspixmapbuf;
-}
-
-/* This function puts a GstEvasPixmapBuffer on a GstEvasPixmapSink's pixmap. Returns FALSE
- * if no pixmap was available */
-static gboolean
-gst_evaspixmap_buffer_put (GstEvasPixmapSink *evaspixmapsink, GstEvasPixmapBuffer *evaspixmapbuf)
-{
- GstVideoRectangle result;
-
-#ifdef GST_EXT_XV_ENHANCEMENT
- GstVideoRectangle src_origin = { 0, 0, 0, 0};
- GstVideoRectangle src_input = { 0, 0, 0, 0};
- GstVideoRectangle src = { 0, 0, 0, 0};
- GstVideoRectangle dst = { 0, 0, 0, 0};
- int rotate = 0;
- int ret = 0;
-#endif
-
- /* We take the flow_lock. If expose is in there we don't want to run
- concurrently from the data flow thread */
- g_mutex_lock (evaspixmapsink->flow_lock);
-
- if (G_UNLIKELY (evaspixmapsink->xpixmap == NULL)) {
- GST_WARNING_OBJECT (evaspixmapsink, "xpixmap is NULL. Skip buffer_put." );
- g_mutex_unlock(evaspixmapsink->flow_lock);
- return FALSE;
- }
- if (evaspixmapsink->visible == FALSE) {
- GST_WARNING_OBJECT (evaspixmapsink, "visible is FALSE. Skip buffer_put." );
- g_mutex_unlock(evaspixmapsink->flow_lock);
- return TRUE;
- }
- if (!evaspixmapbuf) {
- GST_WARNING_OBJECT (evaspixmapsink, "evaspixmapbuf is NULL. Skip buffer_put." );
- g_mutex_unlock(evaspixmapsink->flow_lock);
- return TRUE;
- }
-
-#ifdef GST_EXT_XV_ENHANCEMENT
- gst_evaspixmapsink_xpixmap_update_geometry( evaspixmapsink );
-
- src.x = src.y = 0;
- src_origin.x = src_origin.y = src_input.x = src_input.y = 0;
- src_input.w = src_origin.w = evaspixmapsink->video_width;
- src_input.h = src_origin.h = evaspixmapsink->video_height;
- src.w = src_origin.w;
- src.h = src_origin.h;
-
- dst.w = evaspixmapsink->render_rect.w; /* pixmap width */
- dst.h = evaspixmapsink->render_rect.h; /* pixmap heighy */
-
- if (!evaspixmapsink->use_origin_size) {
- switch (evaspixmapsink->display_geometry_method) {
- case DISP_GEO_METHOD_LETTER_BOX:
- gst_video_sink_center_rect (src, dst, &result, TRUE);
- result.x += evaspixmapsink->render_rect.x;
- result.y += evaspixmapsink->render_rect.y;
- GST_DEBUG_OBJECT (evaspixmapsink, "GEO_METHOD : letter box");
- break;
- case DISP_GEO_METHOD_ORIGIN_SIZE:
- gst_video_sink_center_rect (src, dst, &result, FALSE);
- gst_video_sink_center_rect (dst, src, &src_input, FALSE);
- GST_DEBUG_OBJECT (evaspixmapsink, "GEO_METHOD : origin size");
- break;
- case DISP_GEO_METHOD_CROPPED_FULL_SCREEN:
- GST_DEBUG_OBJECT (evaspixmapsink, "GEO_METHOD : cropped full screen");
- gst_video_sink_center_rect(dst, src, &src_input, TRUE);
- result.x = result.y = 0;
- result.w = dst.w;
- result.h = dst.h;
- break;
- case DISP_GEO_METHOD_FULL_SCREEN:
- result.x = result.y = 0;
- result.w = evaspixmapsink->xpixmap->width;
- result.h = evaspixmapsink->xpixmap->height;
- GST_DEBUG_OBJECT (evaspixmapsink, "GEO_METHOD : full screen");
- break;
- case DISP_GEO_METHOD_CUSTOM_ROI:
- result.x = evaspixmapsink->dst_roi.x;
- result.y = evaspixmapsink->dst_roi.y;
- result.w = evaspixmapsink->dst_roi.w;
- result.h = evaspixmapsink->dst_roi.h;
- GST_DEBUG_OBJECT (evaspixmapsink, "GEO_METHOD : custom roi");
- break;
- default:
- break;
- }
- GST_DEBUG_OBJECT (evaspixmapsink, "GEO_METHOD : src(%dx%d), dst(%dx%d), result(%dx%d), result_x(%d), result_y(%d)",
- src.w,src.h,dst.w,dst.h,result.w,result.h,result.x,result.y);
- } else {
- result.x = result.y = 0;
- result.w = evaspixmapsink->xpixmap->width;
- result.h = evaspixmapsink->xpixmap->height;
- GST_DEBUG_OBJECT (evaspixmapsink, "USE ORIGIN SIZE, no geometry method" );
- }
-#else
- if (evaspixmapsink->keep_aspect) {
- GstVideoRectangle src, dst;
- /* We use the calculated geometry from _setcaps as a source to respect
- source and screen pixel aspect ratios. */
- src.w = GST_VIDEO_SINK_WIDTH (evaspixmapsink);
- src.h = GST_VIDEO_SINK_HEIGHT (evaspixmapsink);
- dst.w = evaspixmapsink->render_rect.w;
- dst.h = evaspixmapsink->render_rect.h;
-
- gst_video_sink_center_rect (src, dst, &result, TRUE);
- result.x += evaspixmapsink->render_rect.x;
- result.y += evaspixmapsink->render_rect.y;
- } else {
- memcpy (&result, &evaspixmapsink->render_rect, sizeof (GstVideoRectangle));
- }
-#endif
-
- g_mutex_lock (evaspixmapsink->x_lock);
-
- /* We scale to the pixmap's geometry */
-#ifdef HAVE_XSHM
- if (evaspixmapsink->xcontext->use_xshm) {
- GST_LOG_OBJECT (evaspixmapsink,"XvShmPutImage with image %dx%d and pixmap %dx%d, from xvimage %"
- GST_PTR_FORMAT,
- evaspixmapbuf->width, evaspixmapbuf->height,
- evaspixmapsink->render_rect.w, evaspixmapsink->render_rect.h, evaspixmapbuf);
-
-#ifdef GST_EXT_XV_ENHANCEMENT
- /* Trim as proper size */
- if (src_input.w % 2 == 1) {
- src_input.w += 1;
- }
- if (src_input.h % 2 == 1) {
- src_input.h += 1;
- }
-
- GST_LOG_OBJECT (evaspixmapsink, "screen[%dx%d],pixmap[%d,%d,%dx%d],method[%d],rotate[%d],src[%dx%d],dst[%d,%d,%dx%d],input[%d,%d,%dx%d],result[%d,%d,%dx%d]",
- evaspixmapsink->scr_w, evaspixmapsink->scr_h,
- evaspixmapsink->xpixmap->x, evaspixmapsink->xpixmap->y, evaspixmapsink->xpixmap->width, evaspixmapsink->xpixmap->height,
- evaspixmapsink->display_geometry_method, rotate,
- src_origin.w, src_origin.h,
- dst.x, dst.y, dst.w, dst.h,
- src_input.x, src_input.y, src_input.w, src_input.h,
- result.x, result.y, result.w, result.h );
-
- if (evaspixmapsink->visible) {
- ret = XvShmPutImage (evaspixmapsink->xcontext->disp,
- evaspixmapsink->xcontext->xv_port_id,
- evaspixmapsink->xpixmap->pixmap,
- evaspixmapsink->xpixmap->gc, evaspixmapbuf->xvimage,
- src_input.x, src_input.y, src_input.w, src_input.h,
- result.x, result.y, result.w, result.h, FALSE);
- GST_LOG_OBJECT (evaspixmapsink, "XvShmPutImage return value [%d]", ret );
-#ifdef DUMP_IMG
- int ret = 0;
- char file_name[128];
- int dump_size = evaspixmapbuf->xvimage->data_size;
-
- if(g_cnt<10) {
- GST_INFO ("DUMP IMG_%2.2d : buffer size(%d)", g_cnt, dump_size);
- sprintf(file_name, "/opt/usr/media/DUMP_IMG_%2.2d.dump", g_cnt);
- ret = util_write_rawdata(file_name, evaspixmapbuf->xvimage->data, dump_size);
- if (ret) {
- GST_ERROR_OBJECT (evaspixmapsink, "util_write_rawdata() failed");
- } else
- g_cnt++;
- }
-#endif
- } else {
- GST_WARNING_OBJECT (evaspixmapsink, "visible is FALSE. skip this image..." );
- }
-#else /* GST_EXT_XV_ENHANCEMENT */
- if (evaspixmapsink->visible) {
- XvShmPutImage (evaspixmapsink->xcontext->disp,
- evaspixmapsink->xcontext->xv_port_id,
- evaspixmapsink->xpixmap->pixmap,
- evaspixmapsink->xpixmap->gc, evaspixmapbuf->xvimage,
- evaspixmapsink->disp_x, evaspixmapsink->disp_y,
- evaspixmapsink->disp_width, evaspixmapsink->disp_height,
- result.x, result.y, result.w, result.h, FALSE);
- } else {
- GST_WARNING_OBJECT (evaspixmapsink, "visible is FALSE. skip this image..." );
- }
-#endif /* GST_EXT_XV_ENHANCEMENT */
- } else
-#endif /* HAVE_XSHM */
- {
- if (evaspixmapsink->visible) {
- XvPutImage (evaspixmapsink->xcontext->disp,
- evaspixmapsink->xcontext->xv_port_id,
- evaspixmapsink->xpixmap->pixmap,
- evaspixmapsink->xpixmap->gc, evaspixmapbuf->xvimage,
- evaspixmapsink->disp_x, evaspixmapsink->disp_y,
- evaspixmapsink->disp_width, evaspixmapsink->disp_height,
- result.x, result.y, result.w, result.h);
- } else {
- GST_WARNING_OBJECT (evaspixmapsink, "visible is FALSE. skip this image..." );
- }
- }
- XSync (evaspixmapsink->xcontext->disp, FALSE);
-
- g_mutex_unlock (evaspixmapsink->x_lock);
- g_mutex_unlock (evaspixmapsink->flow_lock);
-
-
- return TRUE;
-}
-
-static int
-drm_init(GstEvasPixmapSink *evaspixmapsink)
-{
- Display *dpy;
- int i = 0;
- int eventBase = 0;
- int errorBase = 0;
- int dri2Major = 0;
- int dri2Minor = 0;
- char *driverName = NULL;
- char *deviceName = NULL;
- struct drm_auth auth_arg = {0};
-
- evaspixmapsink->drm_fd = -1;
-
- dpy = XOpenDisplay(0);
-
- /* DRI2 */
- if (!DRI2QueryExtension(dpy, &eventBase, &errorBase)) {
- GST_ERROR_OBJECT (evaspixmapsink,"failed to DRI2QueryExtension()");
- goto ERROR_CASE;
- }
-
- if (!DRI2QueryVersion(dpy, &dri2Major, &dri2Minor)) {
- GST_ERROR_OBJECT (evaspixmapsink,"failed to DRI2QueryVersion");
- goto ERROR_CASE;
- }
-
- if (!DRI2Connect(dpy, RootWindow(dpy, DefaultScreen(dpy)), &driverName, &deviceName)) {
- GST_ERROR_OBJECT (evaspixmapsink,"failed to DRI2Connect");
- goto ERROR_CASE;
- }
-
- if (!driverName || !deviceName) {
- GST_ERROR_OBJECT (evaspixmapsink,"driverName or deviceName is not valid");
- goto ERROR_CASE;
- }
-
- GST_INFO_OBJECT (evaspixmapsink,"Open drm device : %s", deviceName);
-
- /* get the drm_fd though opening the deviceName */
- evaspixmapsink->drm_fd = open(deviceName, O_RDWR);
- if (evaspixmapsink->drm_fd < 0) {
- GST_ERROR_OBJECT (evaspixmapsink,"cannot open drm device (%s)", deviceName);
- goto ERROR_CASE;
- }
-
- /* get magic from drm to authentication */
- if (ioctl(evaspixmapsink->drm_fd, DRM_IOCTL_GET_MAGIC, &auth_arg)) {
- GST_ERROR_OBJECT (evaspixmapsink,"cannot get drm auth magic");
- close(evaspixmapsink->drm_fd);
- evaspixmapsink->drm_fd = -1;
- goto ERROR_CASE;
- }
-
- if (!DRI2Authenticate(dpy, RootWindow(dpy, DefaultScreen(dpy)), auth_arg.magic)) {
- GST_ERROR_OBJECT (evaspixmapsink,"cannot get drm authentication from X");
- close(evaspixmapsink->drm_fd);
- evaspixmapsink->drm_fd = -1;
- goto ERROR_CASE;
- }
-
- /* init gem handle */
- for (i = 0; i < MAX_GEM_BUFFER_NUM; i++) {
- evaspixmapsink->gem_info[i].dmabuf_fd = 0;
- evaspixmapsink->gem_info[i].gem_handle = 0;
- evaspixmapsink->gem_info[i].gem_name = 0;
- }
-
- XCloseDisplay(dpy);
- free(driverName);
- free(deviceName);
-
- return 0;
-
-ERROR_CASE:
- XCloseDisplay(dpy);
- if (driverName) {
- free(driverName);
- }
- if (deviceName) {
- free(deviceName);
- }
-
- return -1;
-}
-
-static void
-drm_fini(GstEvasPixmapSink *evaspixmapsink)
-{
- if (evaspixmapsink->drm_fd >= 0) {
- int i = 0;
- for (i = 0; i < MAX_GEM_BUFFER_NUM; i++) {
- if (evaspixmapsink->gem_info[i].dmabuf_fd > 0) {
- GST_INFO_OBJECT (evaspixmapsink,"close gem_handle(%u)", evaspixmapsink->gem_info[i].gem_handle);
- drm_close_gem(evaspixmapsink, evaspixmapsink->gem_info[i].gem_handle);
-
- evaspixmapsink->gem_info[i].dmabuf_fd = 0;
- evaspixmapsink->gem_info[i].gem_handle = 0;
- evaspixmapsink->gem_info[i].gem_name = 0;
- } else {
- break;
- }
- }
- GST_INFO_OBJECT (evaspixmapsink,"close drm_fd(%d)", evaspixmapsink->drm_fd);
- close(evaspixmapsink->drm_fd);
- evaspixmapsink->drm_fd = -1;
- }
-}
-
-static unsigned int
-drm_convert_dmabuf_gemname(GstEvasPixmapSink *evaspixmapsink, int dmabuf_fd)
-{
- struct drm_prime_handle prime_arg = {0,};
- struct drm_gem_flink flink_arg = {0,};
- int i = 0;
-
- if (evaspixmapsink->drm_fd < 0) {
- GST_ERROR_OBJECT (evaspixmapsink,"DRM is not opened");
- return 0;
- }
-
- if (dmabuf_fd <= 0) {
- GST_DEBUG_OBJECT (evaspixmapsink,"Ignore wrong dmabuf fd(%d)", dmabuf_fd); /* temporarily change log level to DEBUG for reducing WARNING level log */
- return 0;
- }
-
- /* check duplicated dmabuf fd */
- for (i = 0 ; i < MAX_GEM_BUFFER_NUM ; i++) {
- if (evaspixmapsink->gem_info[i].dmabuf_fd == dmabuf_fd) {
- GST_LOG_OBJECT (evaspixmapsink,"already got fd(%u) with name(%u)", dmabuf_fd, evaspixmapsink->gem_info[i].gem_name);
- return evaspixmapsink->gem_info[i].gem_name;
- }
-
- if (evaspixmapsink->gem_info[i].dmabuf_fd == 0) {
- GST_LOG_OBJECT (evaspixmapsink,"empty gem_info[%d] found", i);
- break;
- }
- }
-
- if (i == MAX_GEM_BUFFER_NUM) {
- GST_WARNING_OBJECT (evaspixmapsink,"too many buffers[dmabuf_fd(%d). skip it]", dmabuf_fd);
- return 0;
- }
-
- evaspixmapsink->gem_info[i].dmabuf_fd = dmabuf_fd;
- prime_arg.fd = dmabuf_fd;
- if (ioctl(evaspixmapsink->drm_fd, DRM_IOCTL_PRIME_FD_TO_HANDLE, &prime_arg)) {
- GST_ERROR_OBJECT (evaspixmapsink,"non dmabuf fd(%d)", dmabuf_fd);
- return 0;
- }
-
- evaspixmapsink->gem_info[i].gem_handle = prime_arg.handle;
- GST_LOG_OBJECT (evaspixmapsink,"gem_info[%d].gem_handle = %u", i, prime_arg.handle);
-
- flink_arg.handle = prime_arg.handle;
- if (ioctl(evaspixmapsink->drm_fd, DRM_IOCTL_GEM_FLINK, &flink_arg)) {
- GST_ERROR_OBJECT (evaspixmapsink,"cannot convert drm handle to name");
- return 0;
- }
-
- evaspixmapsink->gem_info[i].gem_name = flink_arg.name;
- GST_LOG_OBJECT (evaspixmapsink,"gem_info[%d].gem_name = %u", i, flink_arg.name);
-
- return flink_arg.name;
-}
-
-static void
-drm_close_gem(GstEvasPixmapSink *evaspixmapsink, unsigned int gem_handle)
-{
- struct drm_gem_close close_arg = {0,};
-
- if (evaspixmapsink->drm_fd < 0) {
- GST_ERROR_OBJECT (evaspixmapsink,"DRM is not opened");
- return;
- }
-
- if (gem_handle == 0) {
- GST_ERROR_OBJECT (evaspixmapsink,"invalid gem_handle(%d)",gem_handle);
- return;
- }
-
- close_arg.handle = gem_handle;
- if (gem_handle > 0 && ioctl(evaspixmapsink->drm_fd, DRM_IOCTL_GEM_CLOSE, &close_arg)) {
- GST_ERROR_OBJECT (evaspixmapsink,"cannot close drm gem handle(%d)", gem_handle);
- return;
- }
-
- return;
-}
-
-G_DEFINE_TYPE_EXTENDED(GstEvasPixmapSink, gst_evaspixmapsink, GST_TYPE_VIDEO_SINK, 0,
- G_IMPLEMENT_INTERFACE(GST_TYPE_NAVIGATION, gst_evaspixmapsink_navigation_init)
- G_IMPLEMENT_INTERFACE(GST_TYPE_COLOR_BALANCE, gst_evaspixmapsink_colorbalance_init)
- G_IMPLEMENT_INTERFACE(GST_TYPE_PROPERTY_PROBE, gst_evaspixmapsink_property_probe_interface_init));
-
-
-/* This function destroys a GstXPixmap */
-static void
-gst_evaspixmapsink_xpixmap_destroy (GstEvasPixmapSink *evaspixmapsink, GstXPixmap *xpixmap)
-{
- g_return_if_fail (xpixmap != NULL);
- g_return_if_fail (GST_IS_EVASPIXMAPSINK (evaspixmapsink));
-
- g_mutex_lock (evaspixmapsink->x_lock);
-
- if(evaspixmapsink->xpixmap->pixmap) {
- XFreePixmap(evaspixmapsink->xcontext->disp, evaspixmapsink->xpixmap->pixmap);
- evaspixmapsink->xpixmap->pixmap = NULL;
- GST_DEBUG_OBJECT (evaspixmapsink,"Free pixmap");
- }
-
- if (xpixmap->gc) {
- XFreeGC (evaspixmapsink->xcontext->disp, xpixmap->gc);
- }
-
- XSync (evaspixmapsink->xcontext->disp, FALSE);
-
- g_mutex_unlock (evaspixmapsink->x_lock);
-
- g_free (xpixmap);
-}
-
-static void
-gst_evaspixmapsink_xpixmap_update_geometry (GstEvasPixmapSink *evaspixmapsink)
-{
-#ifdef GST_EXT_XV_ENHANCEMENT
- Window root_window;
- XWindowAttributes root_attr;
-
- int cur_pixmap_x = 0;
- int cur_pixmap_y = 0;
- unsigned int cur_pixmap_width = 0;
- unsigned int cur_pixmap_height = 0;
- unsigned int cur_pixmap_border_width = 0;
- unsigned int cur_pixmap_depth = 0;
-#else
- XWindowAttributes attr;
-#endif
- g_return_if_fail (GST_IS_EVASPIXMAPSINK (evaspixmapsink));
-
- /* Update the window geometry */
- g_mutex_lock (evaspixmapsink->x_lock);
- if (G_UNLIKELY (evaspixmapsink->xpixmap == NULL)) {
- g_mutex_unlock (evaspixmapsink->x_lock);
- return;
- }
-
-#ifdef GST_EXT_XV_ENHANCEMENT
- /* Get root window and size of current pixmap */
- XGetGeometry( evaspixmapsink->xcontext->disp, evaspixmapsink->xpixmap->pixmap, &root_window,
- &cur_pixmap_x, &cur_pixmap_y, /* relative x, y, for pixmap these are alway 0 */
- &cur_pixmap_width, &cur_pixmap_height,
- &cur_pixmap_border_width, &cur_pixmap_depth ); /* cur_pixmap_border_width, cur_pixmap_depth are not used */
-
- evaspixmapsink->xpixmap->width = cur_pixmap_width;
- evaspixmapsink->xpixmap->height = cur_pixmap_height;
-
- evaspixmapsink->xpixmap->x = cur_pixmap_x;
- evaspixmapsink->xpixmap->y = cur_pixmap_y;
-
- /* Get size of root window == size of screen */
- XGetWindowAttributes(evaspixmapsink->xcontext->disp, root_window, &root_attr);
-
- evaspixmapsink->scr_w = root_attr.width;
- evaspixmapsink->scr_h = root_attr.height;
-
- if (!evaspixmapsink->have_render_rect) {
- evaspixmapsink->render_rect.x = evaspixmapsink->render_rect.y = 0;
- evaspixmapsink->render_rect.w = cur_pixmap_width;
- evaspixmapsink->render_rect.h = cur_pixmap_height;
- }
-
- GST_LOG_OBJECT (evaspixmapsink,"screen size %dx%d, current pixmap geometry %d,%d,%dx%d, render_rect %d,%d,%dx%d",
- evaspixmapsink->scr_w, evaspixmapsink->scr_h,
- evaspixmapsink->xpixmap->x, evaspixmapsink->xpixmap->y,
- evaspixmapsink->xpixmap->width, evaspixmapsink->xpixmap->height,
- evaspixmapsink->render_rect.x, evaspixmapsink->render_rect.y,
- evaspixmapsink->render_rect.w, evaspixmapsink->render_rect.h);
-#else
- XGetWindowAttributes (evaspixmapsink->xcontext->disp, evaspixmapsink->xpixmap->pixmap, &attr);
-
- evaspixmapsink->xpixmap->width = attr.width;
- evaspixmapsink->xpixmap->height = attr.height;
-
- if (!evaspixmapsink->have_render_rect) {
- evaspixmapsink->render_rect.x = evaspixmapsink->render_rect.y = 0;
- evaspixmapsink->render_rect.w = attr.width;
- evaspixmapsink->render_rect.h = attr.height;
- }
-#endif
- g_mutex_unlock (evaspixmapsink->x_lock);
-}
-
-static void
-gst_evaspixmapsink_xpixmap_clear (GstEvasPixmapSink *evaspixmapsink, GstXPixmap *xpixmap)
-{
- g_return_if_fail (xpixmap != NULL);
- g_return_if_fail (GST_IS_EVASPIXMAPSINK (evaspixmapsink));
-
- if (!xpixmap->pixmap) {
- GST_WARNING_OBJECT (evaspixmapsink,"pixmap was not created..");
- return;
- }
-
- g_mutex_lock (evaspixmapsink->x_lock);
-
- if( evaspixmapsink->stop_video ) {
- XvStopVideo (evaspixmapsink->xcontext->disp, evaspixmapsink->xcontext->xv_port_id, xpixmap->pixmap);
- }
- /* Preview area is not updated before other UI is updated in the screen. */
- XSetForeground (evaspixmapsink->xcontext->disp, xpixmap->gc, evaspixmapsink->xcontext->black);
- XFillRectangle (evaspixmapsink->xcontext->disp, xpixmap->pixmap, xpixmap->gc,
- evaspixmapsink->render_rect.x, evaspixmapsink->render_rect.y, evaspixmapsink->render_rect.w, evaspixmapsink->render_rect.h);
-
- XSync (evaspixmapsink->xcontext->disp, FALSE);
-
- g_mutex_unlock (evaspixmapsink->x_lock);
-}
-
-/* This function commits our internal colorbalance settings to our grabbed Xv
- port. If the xcontext is not initialized yet it simply returns */
-static void
-gst_evaspixmapsink_update_colorbalance (GstEvasPixmapSink *evaspixmapsink)
-{
- GList *channels = NULL;
-
- g_return_if_fail (GST_IS_EVASPIXMAPSINK (evaspixmapsink));
-
- /* If we haven't initialized the X context we can't update anything */
- if (evaspixmapsink->xcontext == NULL)
- return;
-
- /* Don't set the attributes if they haven't been changed, to avoid
- * rounding errors changing the values */
- if (!evaspixmapsink->cb_changed)
- return;
-
- /* For each channel of the colorbalance we calculate the correct value
- doing range conversion and then set the Xv port attribute to match our
- values. */
- channels = evaspixmapsink->xcontext->channels_list;
-
- while (channels) {
- if (channels->data && GST_IS_COLOR_BALANCE_CHANNEL (channels->data)) {
- GstColorBalanceChannel *channel = NULL;
- Atom prop_atom;
- gint value = 0;
- gdouble convert_coef;
-
- channel = GST_COLOR_BALANCE_CHANNEL (channels->data);
- g_object_ref (channel);
-
- /* Our range conversion coef */
- convert_coef = (channel->max_value - channel->min_value) / 2000.0;
-
- if (g_ascii_strcasecmp (channel->label, "XV_HUE") == 0) {
- value = evaspixmapsink->hue;
- } else if (g_ascii_strcasecmp (channel->label, "XV_SATURATION") == 0) {
- value = evaspixmapsink->saturation;
- } else if (g_ascii_strcasecmp (channel->label, "XV_CONTRAST") == 0) {
- value = evaspixmapsink->contrast;
- } else if (g_ascii_strcasecmp (channel->label, "XV_BRIGHTNESS") == 0) {
- value = evaspixmapsink->brightness;
- } else {
- g_warning ("got an unknown channel %s", channel->label);
- g_object_unref (channel);
- return;
- }
-
- /* Committing to Xv port */
- g_mutex_lock (evaspixmapsink->x_lock);
- prop_atom =
- XInternAtom (evaspixmapsink->xcontext->disp, channel->label, True);
- if (prop_atom != None) {
- int xv_value;
- xv_value =
- floor (0.5 + (value + 1000) * convert_coef + channel->min_value);
- XvSetPortAttribute (evaspixmapsink->xcontext->disp,
- evaspixmapsink->xcontext->xv_port_id, prop_atom, xv_value);
- }
- g_mutex_unlock (evaspixmapsink->x_lock);
-
- g_object_unref (channel);
- }
- channels = g_list_next (channels);
- }
-}
-
-static void
-gst_lookup_xv_port_from_adaptor (GstXContext *xcontext, XvAdaptorInfo *adaptors, int adaptor_no)
-{
- gint j;
- gint res;
-
- /* Do we support XvImageMask ? */
- if (!(adaptors[adaptor_no].type & XvImageMask)) {
- GST_DEBUG ("XV Adaptor %s has no support for XvImageMask", adaptors[adaptor_no].name);
- return;
- }
-
- /* We found such an adaptor, looking for an available port */
- for (j = 0; j < adaptors[adaptor_no].num_ports && !xcontext->xv_port_id; j++) {
- /* We try to grab the port */
- res = XvGrabPort (xcontext->disp, adaptors[adaptor_no].base_id + j, 0);
- if (Success == res) {
- xcontext->xv_port_id = adaptors[adaptor_no].base_id + j;
- GST_DEBUG ("XV Adaptor %s with %ld ports", adaptors[adaptor_no].name, adaptors[adaptor_no].num_ports);
- } else {
- GST_DEBUG ("GrabPort %d for XV Adaptor %s failed: %d", j, adaptors[adaptor_no].name, res);
- }
- }
-}
-
-/* This function generates a caps with all supported format by the first
- Xv grabable port we find. We store each one of the supported formats in a
- format list and append the format to a newly created caps that we return
- If this function does not return NULL because of an error, it also grabs
- the port via XvGrabPort */
-static GstCaps*
-gst_evaspixmapsink_get_xv_support (GstEvasPixmapSink *evaspixmapsink, GstXContext *xcontext)
-{
- gint i;
- XvAdaptorInfo *adaptors;
- gint nb_formats;
- XvImageFormatValues *formats = NULL;
- guint nb_encodings;
- XvEncodingInfo *encodings = NULL;
- gulong max_w = G_MAXINT, max_h = G_MAXINT;
- GstCaps *caps = NULL;
- GstCaps *rgb_caps = NULL;
-
- g_return_val_if_fail (xcontext != NULL, NULL);
-
- /* First let's check that XVideo extension is available */
- if (!XQueryExtension (xcontext->disp, "XVideo", &i, &i, &i)) {
- GST_ELEMENT_ERROR (evaspixmapsink, RESOURCE, SETTINGS,
- ("Could not initialise Xv output"),
- ("XVideo extension is not available"));
- return NULL;
- }
-
- /* Then we get adaptors list */
- if (Success != XvQueryAdaptors (xcontext->disp, xcontext->root,
- &xcontext->nb_adaptors, &adaptors)) {
- GST_ELEMENT_ERROR (evaspixmapsink, RESOURCE, SETTINGS,
- ("Could not initialise Xv output"),
- ("Failed getting XV adaptors list"));
- return NULL;
- }
-
- xcontext->xv_port_id = 0;
-
- GST_DEBUG_OBJECT (evaspixmapsink,"Found %u XV adaptor(s)", xcontext->nb_adaptors);
-
- xcontext->adaptors =
- (gchar **) g_malloc0 (xcontext->nb_adaptors * sizeof (gchar *));
-
- /* Now fill up our adaptor name array */
- for (i = 0; i < xcontext->nb_adaptors; i++) {
- xcontext->adaptors[i] = g_strdup (adaptors[i].name);
- }
-
- if (evaspixmapsink->adaptor_no < xcontext->nb_adaptors) {
- /* Find xv port from user defined adaptor */
- gst_lookup_xv_port_from_adaptor (xcontext, adaptors, evaspixmapsink->adaptor_no);
- }
-
- if (!xcontext->xv_port_id) {
- /* Now search for an adaptor that supports XvImageMask */
- for (i = 0; i < xcontext->nb_adaptors && !xcontext->xv_port_id; i++) {
- gst_lookup_xv_port_from_adaptor (xcontext, adaptors, i);
- evaspixmapsink->adaptor_no = i;
- }
- }
-
- XvFreeAdaptorInfo (adaptors);
-
- if (!xcontext->xv_port_id) {
- evaspixmapsink->adaptor_no = -1;
- GST_ELEMENT_ERROR (evaspixmapsink, RESOURCE, BUSY,
- ("Could not initialise Xv output"), ("No port available"));
- return NULL;
- }
-
- /* Set XV_AUTOPAINT_COLORKEY and XV_DOUBLE_BUFFER and XV_COLORKEY */
- {
- int count, todo = 3;
- XvAttribute *const attr = XvQueryPortAttributes (xcontext->disp,
- xcontext->xv_port_id, &count);
- static const char autopaint[] = "XV_AUTOPAINT_COLORKEY";
- static const char dbl_buffer[] = "XV_DOUBLE_BUFFER";
- static const char colorkey[] = "XV_COLORKEY";
-
- GST_DEBUG_OBJECT (evaspixmapsink,"Checking %d Xv port attributes", count);
-
- evaspixmapsink->have_autopaint_colorkey = FALSE;
- evaspixmapsink->have_double_buffer = FALSE;
- evaspixmapsink->have_colorkey = FALSE;
-
- for (i = 0; ((i < count) && todo); i++)
- if (!strcmp (attr[i].name, autopaint)) {
- const Atom atom = XInternAtom (xcontext->disp, autopaint, False);
-
- /* turn on autopaint colorkey */
- XvSetPortAttribute (xcontext->disp, xcontext->xv_port_id, atom,
- (evaspixmapsink->autopaint_colorkey ? 1 : 0));
- todo--;
- evaspixmapsink->have_autopaint_colorkey = TRUE;
- } else if (!strcmp (attr[i].name, dbl_buffer)) {
- const Atom atom = XInternAtom (xcontext->disp, dbl_buffer, False);
-
- XvSetPortAttribute (xcontext->disp, xcontext->xv_port_id, atom,
- (evaspixmapsink->double_buffer ? 1 : 0));
- todo--;
- evaspixmapsink->have_double_buffer = TRUE;
- } else if (!strcmp (attr[i].name, colorkey)) {
- /* Set the colorkey, default is something that is dark but hopefully
- * won't randomly appear on the screen elsewhere (ie not black or greys)
- * can be overridden by setting "colorkey" property
- */
- const Atom atom = XInternAtom (xcontext->disp, colorkey, False);
- guint32 ckey = 0;
- gboolean set_attr = TRUE;
- guint cr, cg, cb;
-
- /* set a colorkey in the right format RGB565/RGB888
- * We only handle these 2 cases, because they're the only types of
- * devices we've encountered. If we don't recognise it, leave it alone
- */
- cr = (evaspixmapsink->colorkey >> 16);
- cg = (evaspixmapsink->colorkey >> 8) & 0xFF;
- cb = (evaspixmapsink->colorkey) & 0xFF;
- switch (xcontext->depth) {
- case 16: /* RGB 565 */
- cr >>= 3;
- cg >>= 2;
- cb >>= 3;
- ckey = (cr << 11) | (cg << 5) | cb;
- break;
- case 24:
- case 32: /* RGB 888 / ARGB 8888 */
- ckey = (cr << 16) | (cg << 8) | cb;
- break;
- default:
- GST_DEBUG_OBJECT (evaspixmapsink,"Unknown bit depth %d for Xv Colorkey - not adjusting", xcontext->depth);
- set_attr = FALSE;
- break;
- }
-
- if (set_attr) {
- ckey = CLAMP (ckey, (guint32) attr[i].min_value,
- (guint32) attr[i].max_value);
- GST_LOG_OBJECT (evaspixmapsink,"Setting color key for display depth %d to 0x%x", xcontext->depth, ckey);
-
- XvSetPortAttribute (xcontext->disp, xcontext->xv_port_id, atom,
- (gint) ckey);
- }
- todo--;
- evaspixmapsink->have_colorkey = TRUE;
- }
-
- XFree (attr);
- }
-
- /* Get the list of encodings supported by the adapter and look for the
- * XV_IMAGE encoding so we can determine the maximum width and height
- * supported */
- XvQueryEncodings (xcontext->disp, xcontext->xv_port_id, &nb_encodings,
- &encodings);
-
- for (i = 0; i < nb_encodings; i++) {
- GST_LOG_OBJECT (evaspixmapsink,
- "Encoding %d, name %s, max wxh %lux%lu rate %d/%d",
- i, encodings[i].name, encodings[i].width, encodings[i].height,
- encodings[i].rate.numerator, encodings[i].rate.denominator);
- if (strcmp (encodings[i].name, "XV_IMAGE") == 0) {
- max_w = encodings[i].width;
- max_h = encodings[i].height;
-#ifdef GST_EXT_XV_ENHANCEMENT
- evaspixmapsink->scr_w = max_w;
- evaspixmapsink->scr_h = max_h;
-#endif
- }
- }
-
- XvFreeEncodingInfo (encodings);
-
- /* We get all image formats supported by our port */
- formats = XvListImageFormats (xcontext->disp,
- xcontext->xv_port_id, &nb_formats);
- caps = gst_caps_new_empty ();
- for (i = 0; i < nb_formats; i++) {
- GstCaps *format_caps = NULL;
- gboolean is_rgb_format = FALSE;
- GstVideoFormat vformat;
-
- /* We set the image format of the xcontext to an existing one. This
- is just some valid image format for making our xshm calls check before
- caps negotiation really happens. */
- xcontext->im_format = formats[i].id;
-
- switch (formats[i].type) {
- case XvRGB:
- {
- XvImageFormatValues *fmt = &(formats[i]);
- gint endianness = G_BIG_ENDIAN;
-
- if (fmt->byte_order == LSBFirst) {
- /* our caps system handles 24/32bpp RGB as big-endian. */
- if (fmt->bits_per_pixel == 24 || fmt->bits_per_pixel == 32) {
- fmt->red_mask = GUINT32_TO_BE (fmt->red_mask);
- fmt->green_mask = GUINT32_TO_BE (fmt->green_mask);
- fmt->blue_mask = GUINT32_TO_BE (fmt->blue_mask);
-
- if (fmt->bits_per_pixel == 24) {
- fmt->red_mask >>= 8;
- fmt->green_mask >>= 8;
- fmt->blue_mask >>= 8;
- }
- } else
- endianness = G_LITTLE_ENDIAN;
- }
-
- format_caps = gst_caps_new_simple ("video/x-raw",
- "endianness", G_TYPE_INT, endianness,
- "depth", G_TYPE_INT, fmt->depth,
- "bpp", G_TYPE_INT, fmt->bits_per_pixel,
- "red_mask", G_TYPE_INT, fmt->red_mask,
- "green_mask", G_TYPE_INT, fmt->green_mask,
- "blue_mask", G_TYPE_INT, fmt->blue_mask,
- "width", GST_TYPE_INT_RANGE, 1, max_w,
- "height", GST_TYPE_INT_RANGE, 1, max_h,
- "framerate", GST_TYPE_FRACTION_RANGE, 0, 1, G_MAXINT, 1, NULL);
-
- is_rgb_format = TRUE;
- break;
- }
- case XvYUV:
- vformat = gst_video_format_from_fourcc (formats[i].id);
- if (vformat == GST_VIDEO_FORMAT_UNKNOWN)
- break;
- format_caps = gst_caps_new_simple ("video/x-raw",
- "format", G_TYPE_STRING, gst_video_format_to_string (vformat),
- "width", GST_TYPE_INT_RANGE, 1, max_w,
- "height", GST_TYPE_INT_RANGE, 1, max_h,
- "framerate", GST_TYPE_FRACTION_RANGE, 0, 1, G_MAXINT, 1, NULL);
- break;
- default:
- g_assert_not_reached ();
- break;
- }
-
- if (format_caps) {
- GstEvasPixmapFormat *format = NULL;
-
- format = g_new0 (GstEvasPixmapFormat, 1);
- if (format) {
- format->format = formats[i].id;
- format->caps = gst_caps_copy (format_caps);
- xcontext->formats_list = g_list_append (xcontext->formats_list, format);
- }
-
- if (is_rgb_format) {
- if (rgb_caps == NULL)
- rgb_caps = format_caps;
- else
- gst_caps_append (rgb_caps, format_caps);
- } else
- gst_caps_append (caps, format_caps);
- }
- }
-
- /* Collected all caps into either the caps or rgb_caps structures.
- * Append rgb_caps on the end of YUV, so that YUV is always preferred */
- if (rgb_caps)
- gst_caps_append (caps, rgb_caps);
-
- if (formats)
- XFree (formats);
-
- GST_DEBUG_OBJECT (evaspixmapsink,"Generated the following caps: %" GST_PTR_FORMAT, caps);
-
- if (gst_caps_is_empty (caps)) {
- gst_caps_unref (caps);
- XvUngrabPort (xcontext->disp, xcontext->xv_port_id, 0);
- GST_ELEMENT_ERROR (evaspixmapsink, STREAM, WRONG_TYPE, (NULL),
- ("No supported format found"));
- return NULL;
- }
-
- return caps;
-}
-
-static gpointer
-gst_evaspixmapsink_event_thread (GstEvasPixmapSink * evaspixmapsink)
-{
- g_return_val_if_fail (GST_IS_EVASPIXMAPSINK (evaspixmapsink), NULL);
- int damage_base = 0;
- int damage_err_base = 0;
- int damage_case = 0;
- XEvent e;
-
- GST_OBJECT_LOCK (evaspixmapsink);
-
- if (!XDamageQueryExtension(evaspixmapsink->xcontext->disp, &damage_base, &damage_err_base)) {
- GST_ERROR_OBJECT (evaspixmapsink,"XDamageQueryExtension() failed");
- return NULL;
- }
- damage_case = (int)damage_base + XDamageNotify;
-
- while (evaspixmapsink->running) {
- GST_OBJECT_UNLOCK (evaspixmapsink);
- if (evaspixmapsink->xpixmap) {
- g_mutex_lock (evaspixmapsink->x_lock);
- while (XPending (evaspixmapsink->xcontext->disp)) {
- XNextEvent (evaspixmapsink->xcontext->disp, &e);
- if (e.type == damage_case ) {
- XDamageNotifyEvent *damage_ev = (XDamageNotifyEvent *)&e;
- if (damage_ev->drawable == evaspixmapsink->xpixmap->pixmap) {
- ecore_pipe_write(evaspixmapsink->epipe, evaspixmapsink, sizeof(GstEvasPixmapSink));
- GST_DEBUG_OBJECT (evaspixmapsink,"event_handler : after call ecore_pipe_write()");
- }
- XDamageSubtract (evaspixmapsink->xcontext->disp, evaspixmapsink->damage, None, None );
- }
- }
- g_mutex_unlock (evaspixmapsink->x_lock);
- } else {
- GST_DEBUG_OBJECT (evaspixmapsink,"event_handler : what(%d)? skip..", e.type);
- break;
- }
- g_usleep (G_USEC_PER_SEC / 40);
- GST_OBJECT_LOCK (evaspixmapsink);
- }
- GST_OBJECT_UNLOCK (evaspixmapsink);
- return NULL;
-}
-
-static void
-gst_evaspixmapsink_manage_event_thread (GstEvasPixmapSink *evaspixmapsink)
-{
- GThread *thread = NULL;
-
- /* don't start the thread too early */
- if (evaspixmapsink->xcontext == NULL) {
- GST_ERROR_OBJECT (evaspixmapsink,"xcontext is NULL..");
- return;
- }
-
- GST_OBJECT_LOCK (evaspixmapsink);
-
- if (!evaspixmapsink->event_thread) {
- /* Setup our event listening thread */
- GST_DEBUG_OBJECT (evaspixmapsink,"run xevent thread");
- evaspixmapsink->running = TRUE;
- evaspixmapsink->event_thread = g_thread_create ( (GThreadFunc) gst_evaspixmapsink_event_thread, evaspixmapsink, TRUE, NULL);
- } else {
- GST_WARNING_OBJECT (evaspixmapsink,"there already existed the event_thread.. keep going");
- /* Do not finalize the thread in here, Only finalize the thread by calling gst_evaspixmapsink_reset() */
- }
-
- GST_OBJECT_UNLOCK (evaspixmapsink);
-}
-
-
-/* This function calculates the pixel aspect ratio based on the properties
- * in the xcontext structure and stores it there. */
-static void
-gst_evaspixmapsink_calculate_pixel_aspect_ratio (GstXContext *xcontext)
-{
- static const gint par[][2] = {
- {1, 1}, /* regular screen */
- {16, 15}, /* PAL TV */
- {11, 10}, /* 525 line Rec.601 video */
- {54, 59}, /* 625 line Rec.601 video */
- {64, 45}, /* 1280x1024 on 16:9 display */
- {5, 3}, /* 1280x1024 on 4:3 display */
- {4, 3} /* 800x600 on 16:9 display */
- };
- gint i;
- gint index;
- gdouble ratio;
- gdouble delta;
-
-#define DELTA(idx) (ABS (ratio - ((gdouble) par[idx][0] / par[idx][1])))
-
- /* first calculate the "real" ratio based on the X values;
- * which is the "physical" w/h divided by the w/h in pixels of the display */
- ratio = (gdouble) (xcontext->widthmm * xcontext->height)
- / (xcontext->heightmm * xcontext->width);
-
- /* DirectFB's X in 720x576 reports the physical dimensions wrong, so
- * override here */
- if (xcontext->width == 720 && xcontext->height == 576) {
- ratio = 4.0 * 576 / (3.0 * 720);
- }
- GST_DEBUG ("calculated pixel aspect ratio: %f", ratio);
- /* now find the one from par[][2] with the lowest delta to the real one */
- delta = DELTA (0);
- index = 0;
-
- for (i = 1; i < sizeof (par) / (sizeof (gint) * 2); ++i) {
- gdouble this_delta = DELTA (i);
-
- if (this_delta < delta) {
- index = i;
- delta = this_delta;
- }
- }
-
- GST_DEBUG ("Decided on index %d (%d/%d)", index,
- par[index][0], par[index][1]);
-
- g_free (xcontext->par);
- xcontext->par = g_new0 (GValue, 1);
- g_value_init (xcontext->par, GST_TYPE_FRACTION);
- gst_value_set_fraction (xcontext->par, par[index][0], par[index][1]);
- GST_DEBUG ("set xcontext PAR to %d/%d",
- gst_value_get_fraction_numerator (xcontext->par),
- gst_value_get_fraction_denominator (xcontext->par));
-}
-
-/* This function gets the X Display and global info about it. Everything is
- stored in our object and will be cleaned when the object is disposed. Note
- here that caps for supported format are generated without any window or
- image creation */
-static GstXContext*
-gst_evaspixmapsink_xcontext_get (GstEvasPixmapSink *evaspixmapsink)
-{
- GstXContext *xcontext = NULL;
- XPixmapFormatValues *px_formats = NULL;
- gint nb_formats = 0, i, j, N_attr;
- XvAttribute *xv_attr;
- Atom prop_atom;
- const char *channels[4] = { "XV_HUE", "XV_SATURATION", "XV_BRIGHTNESS", "XV_CONTRAST"};
-
- g_return_val_if_fail (GST_IS_EVASPIXMAPSINK (evaspixmapsink), NULL);
-
- xcontext = g_new0 (GstXContext, 1);
- xcontext->im_format = 0;
-
- g_mutex_lock (evaspixmapsink->x_lock);
-
- xcontext->disp = XOpenDisplay (evaspixmapsink->display_name);
-
- if (!xcontext->disp) {
- g_mutex_unlock (evaspixmapsink->x_lock);
- g_free (xcontext);
- GST_ELEMENT_ERROR (evaspixmapsink, RESOURCE, WRITE, ("Could not initialise Xv output"), ("Could not open display"));
- return NULL;
- }
-
- xcontext->screen = DefaultScreenOfDisplay (xcontext->disp);
- xcontext->screen_num = DefaultScreen (xcontext->disp);
- xcontext->visual = DefaultVisual (xcontext->disp, xcontext->screen_num);
- xcontext->root = DefaultRootWindow (xcontext->disp);
- xcontext->white = XWhitePixel (xcontext->disp, xcontext->screen_num);
- xcontext->black = XBlackPixel (xcontext->disp, xcontext->screen_num);
- xcontext->depth = DefaultDepthOfScreen (xcontext->screen);
-
- xcontext->width = DisplayWidth (xcontext->disp, xcontext->screen_num);
- xcontext->height = DisplayHeight (xcontext->disp, xcontext->screen_num);
- xcontext->widthmm = DisplayWidthMM (xcontext->disp, xcontext->screen_num);
- xcontext->heightmm = DisplayHeightMM (xcontext->disp, xcontext->screen_num);
-
- GST_DEBUG_OBJECT (evaspixmapsink,"X reports %dx%d pixels and %d mm x %d mm", xcontext->width, xcontext->height, xcontext->widthmm, xcontext->heightmm);
-
- gst_evaspixmapsink_calculate_pixel_aspect_ratio (xcontext);
- /* We get supported pixmap formats at supported depth */
- px_formats = XListPixmapFormats (xcontext->disp, &nb_formats);
-
- if (!px_formats) {
- XCloseDisplay (xcontext->disp);
- g_mutex_unlock (evaspixmapsink->x_lock);
- g_free (xcontext->par);
- g_free (xcontext);
- GST_ELEMENT_ERROR (evaspixmapsink, RESOURCE, SETTINGS,
- ("Could not initialise Xv output"), ("Could not get pixel formats"));
- return NULL;
- }
-
- /* We get bpp value corresponding to our running depth */
- for (i = 0; i < nb_formats; i++) {
- if (px_formats[i].depth == xcontext->depth)
- xcontext->bpp = px_formats[i].bits_per_pixel;
- }
-
- XFree (px_formats);
-
- xcontext->endianness = (ImageByteOrder (xcontext->disp) == LSBFirst) ? G_LITTLE_ENDIAN : G_BIG_ENDIAN;
-
- /* our caps system handles 24/32bpp RGB as big-endian. */
- if ((xcontext->bpp == 24 || xcontext->bpp == 32) && xcontext->endianness == G_LITTLE_ENDIAN) {
- xcontext->endianness = G_BIG_ENDIAN;
- xcontext->visual->red_mask = GUINT32_TO_BE (xcontext->visual->red_mask);
- xcontext->visual->green_mask = GUINT32_TO_BE (xcontext->visual->green_mask);
- xcontext->visual->blue_mask = GUINT32_TO_BE (xcontext->visual->blue_mask);
- if (xcontext->bpp == 24) {
- xcontext->visual->red_mask >>= 8;
- xcontext->visual->green_mask >>= 8;
- xcontext->visual->blue_mask >>= 8;
- }
- }
-
- xcontext->caps = gst_evaspixmapsink_get_xv_support (evaspixmapsink, xcontext);
-
- if (!xcontext->caps) {
- XCloseDisplay (xcontext->disp);
- g_mutex_unlock (evaspixmapsink->x_lock);
- g_free (xcontext->par);
- g_free (xcontext);
- /* GST_ELEMENT_ERROR is thrown by gst_evaspixmapsink_get_xv_support */
- return NULL;
- }
- #ifdef HAVE_XSHM
- /* Search for XShm extension support */
- if (XShmQueryExtension (xcontext->disp) && gst_evaspixmapsink_check_xshm_calls (xcontext)) {
- xcontext->use_xshm = TRUE;
- GST_DEBUG_OBJECT (evaspixmapsink,"evaspixmapsink is using XShm extension");
- } else
- #endif /* HAVE_XSHM */
- {
- xcontext->use_xshm = FALSE;
- GST_DEBUG_OBJECT (evaspixmapsink,"evaspixmapsink is not using XShm extension");
- }
-
- xv_attr = XvQueryPortAttributes (xcontext->disp, xcontext->xv_port_id, &N_attr);
-
- /* Generate the channels list */
- for (i = 0; i < (sizeof (channels) / sizeof (char *)); i++) {
- XvAttribute *matching_attr = NULL;
-
- /* Retrieve the property atom if it exists. If it doesn't exist,
- * the attribute itself must not either, so we can skip */
- prop_atom = XInternAtom (xcontext->disp, channels[i], True);
- if (prop_atom == None) {
- continue;
- }
-
- if (xv_attr != NULL) {
- for (j = 0; j < N_attr && matching_attr == NULL; ++j) {
- if (!g_ascii_strcasecmp (channels[i], xv_attr[j].name)) {
- matching_attr = xv_attr + j;
- }
- }
- }
-
- if (matching_attr) {
- GstColorBalanceChannel *channel;
- channel = g_object_new (GST_TYPE_COLOR_BALANCE_CHANNEL, NULL);
- channel->label = g_strdup (channels[i]);
- channel->min_value = matching_attr->min_value;
- channel->max_value = matching_attr->max_value;
-
- xcontext->channels_list = g_list_append (xcontext->channels_list, channel);
-
- /* If the colorbalance settings have not been touched we get Xv values
- as defaults and update our internal variables */
- if (!evaspixmapsink->cb_changed) {
- gint val;
- XvGetPortAttribute (xcontext->disp, xcontext->xv_port_id, prop_atom, &val);
- /* Normalize val to [-1000, 1000] */
- val = floor (0.5 + -1000 + 2000 * (val - channel->min_value) / (double) (channel->max_value - channel->min_value));
-
- if (!g_ascii_strcasecmp (channels[i], "XV_HUE")) {
- evaspixmapsink->hue = val;
- } else if (!g_ascii_strcasecmp (channels[i], "XV_SATURATION")) {
- evaspixmapsink->saturation = val;
- } else if (!g_ascii_strcasecmp (channels[i], "XV_BRIGHTNESS")) {
- evaspixmapsink->brightness = val;
- } else if (!g_ascii_strcasecmp (channels[i], "XV_CONTRAST")) {
- evaspixmapsink->contrast = val;
- }
- }
- }
- }
-
- if (xv_attr) {
- XFree (xv_attr);
- }
-
- g_mutex_unlock (evaspixmapsink->x_lock);
-
- return xcontext;
-}
-
-/* This function cleans the X context. Closing the Display, releasing the XV
- port and unrefing the caps for supported formats. */
-static void
-gst_evaspixmapsink_xcontext_clear (GstEvasPixmapSink *evaspixmapsink)
-{
- GList *formats_list, *channels_list;
- GstXContext *xcontext;
- gint i = 0;
-
- g_return_if_fail (GST_IS_EVASPIXMAPSINK (evaspixmapsink));
-
- GST_OBJECT_LOCK (evaspixmapsink);
- if (evaspixmapsink->xcontext == NULL) {
- GST_OBJECT_UNLOCK (evaspixmapsink);
- return;
- }
-
- /* Take the XContext from the sink and clean it up */
- xcontext = evaspixmapsink->xcontext;
- evaspixmapsink->xcontext = NULL;
-
- GST_OBJECT_UNLOCK (evaspixmapsink);
-
- formats_list = xcontext->formats_list;
-
- while (formats_list) {
- GstEvasPixmapFormat *format = formats_list->data;
-
- gst_caps_unref (format->caps);
- g_free (format);
- formats_list = g_list_next (formats_list);
- }
-
- if (xcontext->formats_list)
- g_list_free (xcontext->formats_list);
-
- channels_list = xcontext->channels_list;
-
- while (channels_list) {
- GstColorBalanceChannel *channel = channels_list->data;
-
- g_object_unref (channel);
- channels_list = g_list_next (channels_list);
- }
-
- if (xcontext->channels_list)
- g_list_free (xcontext->channels_list);
-
- gst_caps_unref (xcontext->caps);
-
- for (i = 0; i < xcontext->nb_adaptors; i++) {
- g_free (xcontext->adaptors[i]);
- }
-
- g_free (xcontext->adaptors);
-
- g_free (xcontext->par);
-
- g_mutex_lock (evaspixmapsink->x_lock);
-
- GST_DEBUG_OBJECT (evaspixmapsink,"Closing display and freeing X Context");
-
- XvUngrabPort (xcontext->disp, xcontext->xv_port_id, 0);
-
- XCloseDisplay (xcontext->disp);
-
- g_mutex_unlock (evaspixmapsink->x_lock);
-
- g_free (xcontext);
-}
-
-/* Element stuff */
-
-/* This function tries to get a format matching with a given caps in the
- supported list of formats we generated in gst_evaspixmapsink_get_xv_support */
-static gint
-gst_evaspixmapsink_get_format_from_caps (GstEvasPixmapSink *evaspixmapsink, GstCaps *caps)
-{
- GList *list = NULL;
-
- g_return_val_if_fail (GST_IS_EVASPIXMAPSINK (evaspixmapsink), 0);
-
- list = evaspixmapsink->xcontext->formats_list;
-
- while (list) {
- GstEvasPixmapFormat *format = list->data;
-
- if (format) {
- if (gst_caps_can_intersect (caps, format->caps)) {
- return format->format;
- }
- }
- list = g_list_next (list);
- }
-
- return -1;
-}
-
-static GstCaps *
-gst_evaspixmapsink_getcaps (GstBaseSink *bsink, GstCaps *filter)
-{
- GstEvasPixmapSink *evaspixmapsink;
- GstCaps* pad_caps;
-
- evaspixmapsink = GST_EVASPIXMAPSINK (bsink);
-
- if(filter)
- GST_LOG_OBJECT (evaspixmapsink,"filter caps %" GST_PTR_FORMAT, filter);
- if(evaspixmapsink->xcontext)
- GST_LOG_OBJECT (evaspixmapsink,"context caps %" GST_PTR_FORMAT, evaspixmapsink->xcontext->caps);
-
- if (evaspixmapsink->xcontext)
- return filter ? gst_caps_intersect(filter, evaspixmapsink->xcontext->caps)
- : gst_caps_ref (evaspixmapsink->xcontext->caps);
-
- pad_caps = gst_pad_get_pad_template_caps (GST_VIDEO_SINK_PAD(evaspixmapsink));
- return
- filter ? gst_caps_intersect(filter, pad_caps) : gst_caps_copy (pad_caps);
-}
-
-static gboolean
-gst_evaspixmapsink_setcaps (GstBaseSink *bsink, GstCaps *caps)
-{
- GstEvasPixmapSink *evaspixmapsink;
- GstStructure *structure;
- guint32 im_format = 0;
- gboolean ret;
- gint video_width, video_height;
- gint disp_x, disp_y;
- gint disp_width, disp_height;
- gint video_par_n, video_par_d; /* video's PAR */
- gint display_par_n, display_par_d; /* display's PAR */
- const GValue *caps_par;
- const GValue *caps_disp_reg;
- const GValue *fps;
- guint num, den;
-#ifdef GST_EXT_XV_ENHANCEMENT
- gboolean enable_last_buffer;
-#endif
-
- evaspixmapsink = GST_EVASPIXMAPSINK (bsink);
-
- GST_DEBUG_OBJECT (evaspixmapsink,"In setcaps. Possible caps %" GST_PTR_FORMAT ", setting caps %" GST_PTR_FORMAT, evaspixmapsink->xcontext->caps, caps);
-
- if (!gst_caps_can_intersect (evaspixmapsink->xcontext->caps, caps)) {
- goto incompatible_caps;
- }
-
- evaspixmapsink->negotiated_caps = gst_caps_copy(caps);
- structure = gst_caps_get_structure (caps, 0);
- ret = gst_structure_get_int (structure, "width", &video_width);
- ret &= gst_structure_get_int (structure, "height", &video_height);
- fps = gst_structure_get_value (structure, "framerate");
- ret &= (fps != NULL);
-
- if (!ret) {
- goto incomplete_caps;
- }
-
-#ifdef GST_EXT_XV_ENHANCEMENT
- evaspixmapsink->aligned_width = video_width;
- evaspixmapsink->aligned_height = video_height;
-
- /* get enable-last-buffer */
- g_object_get(G_OBJECT(evaspixmapsink), "enable-last-buffer", &enable_last_buffer, NULL);
- GST_INFO_OBJECT (evaspixmapsink,"current enable-last-buffer : %d", enable_last_buffer);
- /* flush if enable-last-buffer is TRUE */
- if (enable_last_buffer) {
- GST_INFO_OBJECT (evaspixmapsink,"flush last-buffer");
- g_object_set(G_OBJECT(evaspixmapsink), "enable-last-buffer", FALSE, NULL);
- g_object_set(G_OBJECT(evaspixmapsink), "enable-last-buffer", TRUE, NULL);
- }
-#endif
-
- evaspixmapsink->fps_n = gst_value_get_fraction_numerator (fps);
- evaspixmapsink->fps_d = gst_value_get_fraction_denominator (fps);
-
- evaspixmapsink->video_width = video_width;
- evaspixmapsink->video_height = video_height;
-
- im_format = gst_evaspixmapsink_get_format_from_caps (evaspixmapsink, caps);
- if (im_format == -1) {
- goto invalid_format;
- }
-
- /* get aspect ratio from caps if it's present, and
- * convert video width and height to a display width and height
- * using wd / hd = wv / hv * PARv / PARd */
-
- /* get video's PAR */
- caps_par = gst_structure_get_value (structure, "pixel-aspect-ratio");
- if (caps_par) {
- video_par_n = gst_value_get_fraction_numerator (caps_par);
- video_par_d = gst_value_get_fraction_denominator (caps_par);
- } else {
- video_par_n = 1;
- video_par_d = 1;
- }
- /* get display's PAR */
- if (evaspixmapsink->par) {
- display_par_n = gst_value_get_fraction_numerator (evaspixmapsink->par);
- display_par_d = gst_value_get_fraction_denominator (evaspixmapsink->par);
- } else {
- display_par_n = 1;
- display_par_d = 1;
- }
-
- /* get the display region */
- caps_disp_reg = gst_structure_get_value (structure, "display-region");
- if (caps_disp_reg) {
- disp_x = g_value_get_int (gst_value_array_get_value (caps_disp_reg, 0));
- disp_y = g_value_get_int (gst_value_array_get_value (caps_disp_reg, 1));
- disp_width = g_value_get_int (gst_value_array_get_value (caps_disp_reg, 2));
- disp_height = g_value_get_int (gst_value_array_get_value (caps_disp_reg, 3));
- } else {
- disp_x = disp_y = 0;
- disp_width = video_width;
- disp_height = video_height;
- }
-
- if (!gst_video_calculate_display_ratio (&num, &den, video_width, video_height, video_par_n, video_par_d, display_par_n, display_par_d)) {
- goto no_disp_ratio;
- }
-
- evaspixmapsink->disp_x = disp_x;
- evaspixmapsink->disp_y = disp_y;
- evaspixmapsink->disp_width = disp_width;
- evaspixmapsink->disp_height = disp_height;
-
- GST_DEBUG_OBJECT (evaspixmapsink,"video width/height: %dx%d, calculated display ratio: %d/%d", video_width, video_height, num, den);
-
- /* now find a width x height that respects this display ratio.
- * prefer those that have one of w/h the same as the incoming video
- * using wd / hd = num / den */
-
- /* start with same height, because of interlaced video */
- /* check hd / den is an integer scale factor, and scale wd with the PAR */
- if (video_height % den == 0) {
- GST_DEBUG_OBJECT (evaspixmapsink,"keeping video height");
- GST_VIDEO_SINK_WIDTH (evaspixmapsink) = (guint) gst_util_uint64_scale_int (video_height, num, den);
- GST_VIDEO_SINK_HEIGHT (evaspixmapsink) = video_height;
- } else if (video_width % num == 0) {
- GST_DEBUG_OBJECT (evaspixmapsink,"keeping video width");
- GST_VIDEO_SINK_WIDTH (evaspixmapsink) = video_width;
- GST_VIDEO_SINK_HEIGHT (evaspixmapsink) = (guint) gst_util_uint64_scale_int (video_width, den, num);
- } else {
- GST_DEBUG_OBJECT (evaspixmapsink,"approximating while keeping video height");
- GST_VIDEO_SINK_WIDTH (evaspixmapsink) = (guint) gst_util_uint64_scale_int (video_height, num, den);
- GST_VIDEO_SINK_HEIGHT (evaspixmapsink) = video_height;
- }
- GST_DEBUG_OBJECT (evaspixmapsink,"scaling to %dx%d", GST_VIDEO_SINK_WIDTH (evaspixmapsink), GST_VIDEO_SINK_HEIGHT (evaspixmapsink));
-
- /* Creating our window and our image with the display size in pixels */
- if (GST_VIDEO_SINK_WIDTH (evaspixmapsink) <= 0 || GST_VIDEO_SINK_HEIGHT (evaspixmapsink) <= 0) {
- goto no_display_size;
- }
-
- g_mutex_lock (evaspixmapsink->flow_lock);
-
- /* We renew our evaspixmap buffer only if size or format changed;
- * the evaspixmap buffer is the same size as the video pixel size */
- if ((evaspixmapsink->evas_pixmap_buf) && ((im_format != evaspixmapsink->evas_pixmap_buf->im_format)
- || (video_width != evaspixmapsink->evas_pixmap_buf->width) || (video_height != evaspixmapsink->evas_pixmap_buf->height))) {
- GST_DEBUG_OBJECT (evaspixmapsink,"old format %" GST_FOURCC_FORMAT ", new format %" GST_FOURCC_FORMAT,
- GST_FOURCC_ARGS (evaspixmapsink->evas_pixmap_buf->im_format), GST_FOURCC_ARGS (im_format));
- GST_DEBUG_OBJECT (evaspixmapsink,"renewing evaspixmap buffer");
- g_boxed_free(GST_TYPE_EVASPIXMAP_BUFFER, evaspixmapsink->evas_pixmap_buf);
- evaspixmapsink->evas_pixmap_buf = NULL;
- }
-
- g_mutex_unlock (evaspixmapsink->flow_lock);
-
- if (evaspixmapsink->eo) {
- if (!gst_evaspixmapsink_xpixmap_link (evaspixmapsink)) {
- GST_ERROR_OBJECT (evaspixmapsink,"link evas image object with pixmap failed...");
- return FALSE;
- } else {
- gst_evaspixmapsink_manage_event_thread (evaspixmapsink);
- }
- } else {
- GST_ERROR_OBJECT (evaspixmapsink,"setcaps success, but there is no evas image object..");
- return FALSE;
- }
-
- return TRUE;
-
- /* ERRORS */
- incompatible_caps:
- {
- GST_ERROR_OBJECT (evaspixmapsink,"caps incompatible");
- return FALSE;
- }
- incomplete_caps:
- {
- GST_DEBUG_OBJECT (evaspixmapsink,"Failed to retrieve either width, ""height or framerate from intersected caps");
- return FALSE;
- }
- invalid_format:
- {
- GST_DEBUG_OBJECT (evaspixmapsink,"Could not locate image format from caps %" GST_PTR_FORMAT, caps);
- return FALSE;
- }
- no_disp_ratio:
- {
- GST_ELEMENT_ERROR (evaspixmapsink, CORE, NEGOTIATION, (NULL), ("Error calculating the output display ratio of the video."));
- return FALSE;
- }
- no_display_size:
- {
- GST_ELEMENT_ERROR (evaspixmapsink, CORE, NEGOTIATION, (NULL), ("Error calculating the output display ratio of the video."));
- return FALSE;
- }
-}
-
-static GstStateChangeReturn
-gst_evaspixmapsink_change_state (GstElement *element, GstStateChange transition)
-{
- GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
- GstEvasPixmapSink *evaspixmapsink;
-
- evaspixmapsink = GST_EVASPIXMAPSINK (element);
-
- switch (transition) {
- case GST_STATE_CHANGE_NULL_TO_READY:
- GST_DEBUG_OBJECT (evaspixmapsink,"GST_STATE_CHANGE_NULL_TO_READY");
-
- /* open drm to use gem */
- if (drm_init(evaspixmapsink)) {
- GST_ERROR_OBJECT (evaspixmapsink,"drm_init() failure");
- return GST_STATE_CHANGE_FAILURE;
- }
-
- /* check if there exist evas image object, need to write code related to making internal evas image object */
- if (!is_evas_image_object (evaspixmapsink->eo)) {
- GST_ERROR_OBJECT (evaspixmapsink,"There is no evas image object..");
- return GST_STATE_CHANGE_FAILURE;
- }
-
- /* Set xcontext and display */
- if (!evaspixmapsink->xcontext) {
- evaspixmapsink->xcontext = gst_evaspixmapsink_xcontext_get (evaspixmapsink);
- if (!evaspixmapsink->xcontext) {
- GST_ERROR_OBJECT (evaspixmapsink,"could not get xcontext..");
- return GST_STATE_CHANGE_FAILURE;
- }
- }
-
- /* update object's par with calculated one if not set yet */
- if (!evaspixmapsink->par) {
- evaspixmapsink->par = g_new0 (GValue, 1);
- gst_value_init_and_copy (evaspixmapsink->par, evaspixmapsink->xcontext->par);
- GST_DEBUG_OBJECT (evaspixmapsink,"set calculated PAR on object's PAR");
- }
-
- /* call XSynchronize with the current value of synchronous */
- GST_DEBUG_OBJECT (evaspixmapsink,"XSynchronize called with %s", evaspixmapsink->synchronous ? "TRUE" : "FALSE");
- XSynchronize (evaspixmapsink->xcontext->disp, evaspixmapsink->synchronous);
- gst_evaspixmapsink_update_colorbalance (evaspixmapsink);
- break;
-
- case GST_STATE_CHANGE_READY_TO_PAUSED:
- GST_DEBUG_OBJECT (evaspixmapsink,"GST_STATE_CHANGE_READY_TO_PAUSED");
- break;
-
- case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
- GST_DEBUG_OBJECT (evaspixmapsink,"GST_STATE_CHANGE_PAUSED_TO_PLAYING");
- break;
-
- default:
- break;
- }
-
- ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
-
- switch (transition) {
- case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
- GST_DEBUG_OBJECT (evaspixmapsink,"GST_STATE_CHANGE_PLAYING_TO_PAUSED");
- break;
-
- case GST_STATE_CHANGE_PAUSED_TO_READY:
- GST_DEBUG_OBJECT (evaspixmapsink,"GST_STATE_CHANGE_PAUSED_TO_READY");
- evaspixmapsink->fps_n = 0;
- evaspixmapsink->fps_d = 1;
- GST_VIDEO_SINK_WIDTH (evaspixmapsink) = 0;
- GST_VIDEO_SINK_HEIGHT (evaspixmapsink) = 0;
- break;
-
- case GST_STATE_CHANGE_READY_TO_NULL:
- GST_DEBUG_OBJECT (evaspixmapsink,"GST_STATE_CHANGE_READY_TO_NULL");
- gst_evaspixmapsink_reset (evaspixmapsink);
- /* close drm */
- drm_fini(evaspixmapsink);
- break;
-
- default:
- break;
- }
- return ret;
-}
-
-static void
-gst_evaspixmapsink_get_times (GstBaseSink *bsink, GstBuffer *buf, GstClockTime *start, GstClockTime *end)
-{
- GstEvasPixmapSink *evaspixmapsink;
-
- evaspixmapsink = GST_EVASPIXMAPSINK (bsink);
-
- if (GST_BUFFER_TIMESTAMP_IS_VALID (buf)) {
- *start = GST_BUFFER_TIMESTAMP (buf);
- if (GST_BUFFER_DURATION_IS_VALID (buf)) {
- *end = *start + GST_BUFFER_DURATION (buf);
- } else {
- if (evaspixmapsink->fps_n > 0) {
- *end = *start +
- gst_util_uint64_scale_int (GST_SECOND, evaspixmapsink->fps_d,
- evaspixmapsink->fps_n);
- }
- }
- }
-}
-
-static GstFlowReturn
-gst_evaspixmapsink_show_frame (GstVideoSink *vsink, GstBuffer *buf)
-{
- GstMapInfo buf_info = GST_MAP_INFO_INIT;
- GstEvasPixmapSink *evaspixmapsink;
-#ifdef GST_EXT_XV_ENHANCEMENT
- XV_PUTIMAGE_DATA_PTR img_data = NULL;
- SCMN_IMGB *scmn_imgb = NULL;
- gint format = 0;
-#endif
- evaspixmapsink = GST_EVASPIXMAPSINK (vsink);
-
-#ifdef GST_EXT_XV_ENHANCEMENT
- if( evaspixmapsink->stop_video ) {
- GST_INFO_OBJECT (evaspixmapsink, "Stop video is TRUE. so skip show frame..." );
- return GST_FLOW_OK;
- }
-#endif
-
- if (!evaspixmapsink->evas_pixmap_buf) {
- GST_DEBUG_OBJECT (evaspixmapsink,"creating our evaspixmap buffer");
-#ifdef GST_EXT_XV_ENHANCEMENT
- format = gst_evaspixmapsink_get_format_from_caps(evaspixmapsink, evaspixmapsink->negotiated_caps);
-
- switch (format) {
- case GST_MAKE_FOURCC('S', 'T', '1', '2'):
- case GST_MAKE_FOURCC('S', 'N', '1', '2'):
- case GST_MAKE_FOURCC('S', '4', '2', '0'):
- case GST_MAKE_FOURCC('S', 'U', 'Y', '2'):
- case GST_MAKE_FOURCC('S', 'U', 'Y', 'V'):
- case GST_MAKE_FOURCC('S', 'Y', 'V', 'Y'):
- gst_buffer_map(buf, &buf_info, GST_MAP_READ);
- scmn_imgb = (SCMN_IMGB *)buf_info.data;
- gst_buffer_unmap(buf, &buf_info);
- if(scmn_imgb == NULL) {
- GST_DEBUG_OBJECT (evaspixmapsink, "scmn_imgb is NULL. Skip buffer put..." );
- return GST_FLOW_OK;
- }
- /* skip buffer if aligned size is smaller than size of caps */
- if (scmn_imgb->s[0] < evaspixmapsink->video_width || scmn_imgb->e[0] < evaspixmapsink->video_height) {
- GST_WARNING_OBJECT (evaspixmapsink,"invalid size[caps:%dx%d,aligned:%dx%d]. Skip this buffer...",
- evaspixmapsink->video_width, evaspixmapsink->video_height, scmn_imgb->s[0], scmn_imgb->e[0]);
- return GST_FLOW_OK;
- }
- evaspixmapsink->aligned_width = scmn_imgb->s[0];
- evaspixmapsink->aligned_height = scmn_imgb->e[0];
- GST_DEBUG_OBJECT (evaspixmapsink,"video width,height[%dx%d]",evaspixmapsink->video_width, evaspixmapsink->video_height);
- GST_INFO_OBJECT (evaspixmapsink,"Use aligned width,height[%dx%d]",evaspixmapsink->aligned_width, evaspixmapsink->aligned_height);
- break;
- default:
- GST_INFO_OBJECT (evaspixmapsink,"Use original width,height of caps");
- break;
- }
-#endif
- evaspixmapsink->evas_pixmap_buf = gst_evaspixmap_buffer_new (evaspixmapsink, evaspixmapsink->negotiated_caps);
-
- if (!evaspixmapsink->evas_pixmap_buf) {
- /* The create method should have posted an informative error */
- goto no_image;
- }
- if (evaspixmapsink->evas_pixmap_buf->size < gst_buffer_get_size (buf)) {
- GST_ELEMENT_ERROR (evaspixmapsink, RESOURCE, WRITE, ("Failed to create output image buffer of %dx%d pixels", evaspixmapsink->evas_pixmap_buf->width, evaspixmapsink->evas_pixmap_buf->height),("XServer allocated buffer size did not match input buffer"));
- gst_evaspixmap_buffer_destroy (evaspixmapsink->evas_pixmap_buf);
- evaspixmapsink->evas_pixmap_buf = NULL;
- goto no_image;
- }
- }
-
-#ifdef GST_EXT_XV_ENHANCEMENT
- switch (evaspixmapsink->evas_pixmap_buf->im_format) {
- /* Cases for specified formats of Samsung extension */
- case GST_MAKE_FOURCC('S', 'T', '1', '2'):
- case GST_MAKE_FOURCC('S', 'N', '1', '2'):
- case GST_MAKE_FOURCC('S', '4', '2', '0'):
- case GST_MAKE_FOURCC('S', 'U', 'Y', '2'):
- case GST_MAKE_FOURCC('S', 'U', 'Y', 'V'):
- case GST_MAKE_FOURCC('S', 'Y', 'V', 'Y'):
- case GST_MAKE_FOURCC('I', 'T', 'L', 'V'):
- {
- GST_DEBUG_OBJECT (evaspixmapsink, "Samsung extension display format activated. fourcc:%c%c%c%c",
- evaspixmapsink->evas_pixmap_buf->im_format, evaspixmapsink->evas_pixmap_buf->im_format>>8,
- evaspixmapsink->evas_pixmap_buf->im_format>>16, evaspixmapsink->evas_pixmap_buf->im_format>>24);
- GstMapInfo buf_info = GST_MAP_INFO_INIT;
-
- if (evaspixmapsink->evas_pixmap_buf->xvimage->data) {
- img_data = (XV_PUTIMAGE_DATA_PTR) evaspixmapsink->evas_pixmap_buf->xvimage->data;
- XV_PUTIMAGE_INIT_DATA(img_data);
- gst_buffer_map(buf, &buf_info, GST_MAP_READ);
- scmn_imgb = (SCMN_IMGB *)buf_info.data;
- gst_buffer_unmap(buf, &buf_info);
- if (scmn_imgb == NULL) {
- GST_DEBUG_OBJECT (evaspixmapsink, "scmn_imgb is NULL. Skip buffer put..." );
- return GST_FLOW_OK;
- }
-
- if (scmn_imgb->buf_share_method == BUF_SHARE_METHOD_PADDR) {
- img_data->YBuf = (unsigned int)scmn_imgb->p[0];
- img_data->CbBuf = (unsigned int)scmn_imgb->p[1];
- img_data->CrBuf = (unsigned int)scmn_imgb->p[2];
- img_data->BufType = XV_BUF_TYPE_LEGACY;
- if (!img_data->YBuf) {
- GST_WARNING_OBJECT (evaspixmapsink, "img_data->YBuf is NULL. skip buffer put..." );
- return GST_FLOW_OK;
- }
- } else { /* BUF_SHARE_METHOD_FD */
- /* convert dma-buf fd into drm gem name */
- img_data->YBuf = drm_convert_dmabuf_gemname(evaspixmapsink, (int)scmn_imgb->dma_buf_fd[0]);
- img_data->CbBuf = drm_convert_dmabuf_gemname(evaspixmapsink, (int)scmn_imgb->dma_buf_fd[1]);
- img_data->CrBuf = drm_convert_dmabuf_gemname(evaspixmapsink, (int)scmn_imgb->dma_buf_fd[2]);
- img_data->BufType = XV_BUF_TYPE_DMABUF;
- if (!img_data->YBuf) {
- GST_WARNING_OBJECT (evaspixmapsink, "img_data->YBuf is NULL. skip buffer put..." );
- return GST_FLOW_OK;
- }
- }
- GST_LOG_OBJECT(evaspixmapsink, "YBuf[%d], CbBuf[%d], CrBuf[%d]",
- img_data->YBuf, img_data->CbBuf, img_data->CrBuf );
- } else {
- GST_WARNING_OBJECT (evaspixmapsink, "xvimage->data is NULL. skip buffer put..." );
- return GST_FLOW_OK;
- }
- break;
- }
- default:
- {
- GST_DEBUG_OBJECT (evaspixmapsink, "Normal format activated. fourcc:%c%c%c%c",
- evaspixmapsink->evas_pixmap_buf->im_format, evaspixmapsink->evas_pixmap_buf->im_format>>8,
- evaspixmapsink->evas_pixmap_buf->im_format>>16, evaspixmapsink->evas_pixmap_buf->im_format>>24);
- gst_buffer_map(buf, &buf_info, GST_MAP_READ);
- memcpy (evaspixmapsink->evas_pixmap_buf->xvimage->data, buf_info.data,
- MIN (buf_info.size, evaspixmapsink->evas_pixmap_buf->size));
- gst_buffer_unmap(buf, &buf_info);
- break;
- }
- }
-#else
- gst_buffer_map(buf, &buf_info, GST_MAP_READ);
- memcpy (evaspixmapsink->evas_pixmap_buf->xvimage->data, buf_info.data, MIN (buf_info.size, evaspixmapsink->evas_pixmap_buf->size));
- gst_buffer_unmap(buf, &buf_info);
-#endif
- if (!gst_evaspixmap_buffer_put (evaspixmapsink, evaspixmapsink->evas_pixmap_buf)) {
- goto no_pixmap;
- }
-
- return GST_FLOW_OK;
-
- /* ERRORS */
- no_image:
- {
- /* No image available. That's very bad ! */
- GST_WARNING_OBJECT (evaspixmapsink,"could not create image");
- return GST_FLOW_ERROR;
- }
- no_pixmap:
- {
- /* No Pixmap available to put our image into */
- GST_WARNING_OBJECT (evaspixmapsink,"could not output image - no pixmap");
- return GST_FLOW_ERROR;
- }
-}
-
-static gboolean
-gst_evaspixmapsink_event (GstBaseSink *sink, GstEvent *event)
-{
- GstEvasPixmapSink *evaspixmapsink = GST_EVASPIXMAPSINK (sink);
-
- switch (GST_EVENT_TYPE (event)) {
- case GST_EVENT_FLUSH_START:
- GST_DEBUG_OBJECT (evaspixmapsink,"GST_EVENT_FLUSH_START");
- break;
- case GST_EVENT_FLUSH_STOP:
- GST_DEBUG_OBJECT (evaspixmapsink,"GST_EVENT_FLUSH_STOP");
- break;
- default:
- break;
- }
- if (GST_BASE_SINK_CLASS (parent_class)->event) {
- return GST_BASE_SINK_CLASS (parent_class)->event (sink, event);
- } else {
- return TRUE;
- }
-}
-
-/* Interfaces stuff */
-
-static void
-gst_evaspixmapsink_navigation_send_event (GstNavigation *navigation, GstStructure *structure)
-{
- GstEvasPixmapSink *evaspixmapsink = GST_EVASPIXMAPSINK (navigation);
- GstPad *peer;
-
- if ((peer = gst_pad_get_peer (GST_VIDEO_SINK_PAD (evaspixmapsink)))) {
- GstEvent *event;
- GstVideoRectangle src, dst, result;
- gdouble x, y, xscale = 1.0, yscale = 1.0;
-
- event = gst_event_new_navigation (structure);
-
- /* We take the flow_lock while we look at the window */
- g_mutex_lock (evaspixmapsink->flow_lock);
-
- if (!evaspixmapsink->xpixmap) {
- g_mutex_unlock (evaspixmapsink->flow_lock);
- return;
- }
-
- if (evaspixmapsink->keep_aspect) {
- /* We get the frame position using the calculated geometry from _setcaps
- that respect pixel aspect ratios */
- src.w = GST_VIDEO_SINK_WIDTH (evaspixmapsink);
- src.h = GST_VIDEO_SINK_HEIGHT (evaspixmapsink);
- dst.w = evaspixmapsink->render_rect.w;
- dst.h = evaspixmapsink->render_rect.h;
-
- gst_video_sink_center_rect (src, dst, &result, TRUE);
- result.x += evaspixmapsink->render_rect.x;
- result.y += evaspixmapsink->render_rect.y;
- } else {
- memcpy (&result, &evaspixmapsink->render_rect, sizeof (GstVideoRectangle));
- }
-
- g_mutex_unlock (evaspixmapsink->flow_lock);
-
- /* We calculate scaling using the original video frames geometry to include
- pixel aspect ratio scaling. */
- xscale = (gdouble) evaspixmapsink->video_width / result.w;
- yscale = (gdouble) evaspixmapsink->video_height / result.h;
-
- /* Converting pointer coordinates to the non scaled geometry */
- if (gst_structure_get_double (structure, "pointer_x", &x)) {
- x = MIN (x, result.x + result.w);
- x = MAX (x - result.x, 0);
- gst_structure_set (structure, "pointer_x", G_TYPE_DOUBLE,
- (gdouble) x * xscale, NULL);
- }
- if (gst_structure_get_double (structure, "pointer_y", &y)) {
- y = MIN (y, result.y + result.h);
- y = MAX (y - result.y, 0);
- gst_structure_set (structure, "pointer_y", G_TYPE_DOUBLE,
- (gdouble) y * yscale, NULL);
- }
-
- gst_pad_send_event (peer, event);
- gst_object_unref (peer);
- }
-}
-
-static void
-gst_evaspixmapsink_navigation_init (GstNavigationInterface *iface)
-{
- iface->send_event = gst_evaspixmapsink_navigation_send_event;
-}
-
-static const GList*
-gst_evaspixmapsink_colorbalance_list_channels (GstColorBalance *balance)
-{
- GstEvasPixmapSink *evaspixmapsink = GST_EVASPIXMAPSINK (balance);
-
- g_return_val_if_fail (GST_IS_EVASPIXMAPSINK (evaspixmapsink), NULL);
-
- if (evaspixmapsink->xcontext)
- return evaspixmapsink->xcontext->channels_list;
- else
- return NULL;
-}
-
-static void
-gst_evaspixmapsink_colorbalance_set_value (GstColorBalance *balance, GstColorBalanceChannel *channel, gint value)
-{
- GstEvasPixmapSink *evaspixmapsink = GST_EVASPIXMAPSINK (balance);
-
- g_return_if_fail (GST_IS_EVASPIXMAPSINK (evaspixmapsink));
- g_return_if_fail (channel->label != NULL);
-
- evaspixmapsink->cb_changed = TRUE;
-
- /* Normalize val to [-1000, 1000] */
- value = floor (0.5 + -1000 + 2000 * (value - channel->min_value) /
- (double) (channel->max_value - channel->min_value));
-
- if (g_ascii_strcasecmp (channel->label, "XV_HUE") == 0) {
- evaspixmapsink->hue = value;
- } else if (g_ascii_strcasecmp (channel->label, "XV_SATURATION") == 0) {
- evaspixmapsink->saturation = value;
- } else if (g_ascii_strcasecmp (channel->label, "XV_CONTRAST") == 0) {
- evaspixmapsink->contrast = value;
- } else if (g_ascii_strcasecmp (channel->label, "XV_BRIGHTNESS") == 0) {
- evaspixmapsink->brightness = value;
- } else {
- g_warning ("got an unknown channel %s", channel->label);
- return;
- }
-
- gst_evaspixmapsink_update_colorbalance (evaspixmapsink);
-}
-
-static gint
-gst_evaspixmapsink_colorbalance_get_value (GstColorBalance *balance, GstColorBalanceChannel *channel)
-{
- GstEvasPixmapSink *evaspixmapsink = GST_EVASPIXMAPSINK (balance);
- gint value = 0;
-
- g_return_val_if_fail (GST_IS_EVASPIXMAPSINK (evaspixmapsink), 0);
- g_return_val_if_fail (channel->label != NULL, 0);
-
- if (g_ascii_strcasecmp (channel->label, "XV_HUE") == 0) {
- value = evaspixmapsink->hue;
- } else if (g_ascii_strcasecmp (channel->label, "XV_SATURATION") == 0) {
- value = evaspixmapsink->saturation;
- } else if (g_ascii_strcasecmp (channel->label, "XV_CONTRAST") == 0) {
- value = evaspixmapsink->contrast;
- } else if (g_ascii_strcasecmp (channel->label, "XV_BRIGHTNESS") == 0) {
- value = evaspixmapsink->brightness;
- } else {
- g_warning ("got an unknown channel %s", channel->label);
- }
-
- /* Normalize val to [channel->min_value, channel->max_value] */
- value = channel->min_value + (channel->max_value - channel->min_value) * (value + 1000) / 2000;
-
- return value;
-}
-
-static void
-gst_evaspixmapsink_colorbalance_init (GstColorBalanceInterface *iface)
-{
- iface->list_channels = gst_evaspixmapsink_colorbalance_list_channels;
- iface->set_value = gst_evaspixmapsink_colorbalance_set_value;
- iface->get_value = gst_evaspixmapsink_colorbalance_get_value;
-}
-
-static const GList *
-gst_evaspixmapsink_probe_get_properties (GstPropertyProbe *probe)
-{
- GObjectClass *klass = G_OBJECT_GET_CLASS (probe);
- static GList *list = NULL;
-
- if (!list) {
- list = g_list_append (NULL, g_object_class_find_property (klass, "device"));
- list = g_list_append (list, g_object_class_find_property (klass, "autopaint-colorkey"));
- list = g_list_append (list, g_object_class_find_property (klass, "double-buffer"));
- list = g_list_append (list, g_object_class_find_property (klass, "colorkey"));
- }
-
- return list;
-}
-
-static void
-gst_evaspixmapsink_probe_probe_property (GstPropertyProbe *probe, guint prop_id, const GParamSpec *pspec)
-{
- GstEvasPixmapSink *evaspixmapsink = GST_EVASPIXMAPSINK (probe);
-
- switch (prop_id) {
- case PROP_DEVICE:
- case PROP_AUTOPAINT_COLORKEY:
- case PROP_DOUBLE_BUFFER:
- case PROP_COLORKEY:
- GST_DEBUG_OBJECT (evaspixmapsink,"probing device list and get capabilities");
- if (!evaspixmapsink->xcontext) {
- GST_DEBUG_OBJECT (evaspixmapsink,"generating xcontext");
- evaspixmapsink->xcontext = gst_evaspixmapsink_xcontext_get (evaspixmapsink);
- if (!evaspixmapsink->xcontext) {
- GST_ERROR_OBJECT (evaspixmapsink,"could not get xcontext..");
- }
- }
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (probe, prop_id, pspec);
- break;
- }
-}
-
-static gboolean
-gst_evaspixmapsink_probe_needs_probe (GstPropertyProbe *probe, guint prop_id, const GParamSpec *pspec)
-{
- GstEvasPixmapSink *evaspixmapsink = GST_EVASPIXMAPSINK (probe);
- gboolean ret = FALSE;
-
- switch (prop_id) {
- case PROP_DEVICE:
- case PROP_AUTOPAINT_COLORKEY:
- case PROP_DOUBLE_BUFFER:
- case PROP_COLORKEY:
- if (evaspixmapsink->xcontext != NULL) {
- ret = FALSE;
- } else {
- ret = TRUE;
- }
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (probe, prop_id, pspec);
- break;
- }
-
- return ret;
-}
-
-static GValueArray *
-gst_evaspixmapsink_probe_get_values (GstPropertyProbe *probe, guint prop_id, const GParamSpec *pspec)
-{
- GstEvasPixmapSink *evaspixmapsink = GST_EVASPIXMAPSINK (probe);
- GValueArray *array = NULL;
-
- if (G_UNLIKELY (!evaspixmapsink->xcontext)) {
- GST_WARNING_OBJECT (evaspixmapsink,"we don't have any xcontext, can't "
- "get values");
- goto beach;
- }
-
- switch (prop_id) {
- case PROP_DEVICE:
- {
- guint i;
- GValue value = { 0 };
-
- array = g_value_array_new (evaspixmapsink->xcontext->nb_adaptors);
- g_value_init (&value, G_TYPE_STRING);
-
- for (i = 0; i < evaspixmapsink->xcontext->nb_adaptors; i++) {
- gchar *adaptor_id_s = g_strdup_printf ("%u", i);
-
- g_value_set_string (&value, adaptor_id_s);
- g_value_array_append (array, &value);
- g_free (adaptor_id_s);
- }
- g_value_unset (&value);
- break;
- }
- case PROP_AUTOPAINT_COLORKEY:
- if (evaspixmapsink->have_autopaint_colorkey) {
- GValue value = { 0 };
-
- array = g_value_array_new (2);
- g_value_init (&value, G_TYPE_BOOLEAN);
- g_value_set_boolean (&value, FALSE);
- g_value_array_append (array, &value);
- g_value_set_boolean (&value, TRUE);
- g_value_array_append (array, &value);
- g_value_unset (&value);
- }
- break;
- case PROP_DOUBLE_BUFFER:
- if (evaspixmapsink->have_double_buffer) {
- GValue value = { 0 };
-
- array = g_value_array_new (2);
- g_value_init (&value, G_TYPE_BOOLEAN);
- g_value_set_boolean (&value, FALSE);
- g_value_array_append (array, &value);
- g_value_set_boolean (&value, TRUE);
- g_value_array_append (array, &value);
- g_value_unset (&value);
- }
- break;
- case PROP_COLORKEY:
- if (evaspixmapsink->have_colorkey) {
- GValue value = { 0 };
-
- array = g_value_array_new (1);
- g_value_init (&value, GST_TYPE_INT_RANGE);
- gst_value_set_int_range (&value, 0, 0xffffff);
- g_value_array_append (array, &value);
- g_value_unset (&value);
- }
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (probe, prop_id, pspec);
- break;
- }
-
-beach:
- return array;
-}
-
-static void
-gst_evaspixmapsink_property_probe_interface_init (GstPropertyProbeInterface *iface)
-{
- iface->get_properties = gst_evaspixmapsink_probe_get_properties;
- iface->probe_property = gst_evaspixmapsink_probe_probe_property;
- iface->needs_probe = gst_evaspixmapsink_probe_needs_probe;
- iface->get_values = gst_evaspixmapsink_probe_get_values;
-}
-
-static gboolean
-gst_evaspixmapsink_xpixmap_link (GstEvasPixmapSink *evaspixmapsink)
-{
- Display *dpy;
- Pixmap *pixmap_id;
- int evas_object_width = 0;
- int evas_object_height = 0;
- int pixmap_width = 0;
- int pixmap_height = 0;
- int xw = 0;
- int xh = 0;
-
- if (!evaspixmapsink) {
- GST_ERROR_OBJECT (evaspixmapsink,"could not get evaspixmapsink..");
- return FALSE;
- }
- g_mutex_lock (evaspixmapsink->flow_lock);
-
- /* Set xcontext and display */
- if (!evaspixmapsink->xcontext) {
- GST_WARNING_OBJECT (evaspixmapsink,"there's no xcontext, try to get one..");
- evaspixmapsink->xcontext = gst_evaspixmapsink_xcontext_get (evaspixmapsink);
- if (!evaspixmapsink->xcontext) {
- GST_ERROR_OBJECT (evaspixmapsink,"could not get xcontext..");
- return FALSE;
- }
- }
-
- dpy = evaspixmapsink->xcontext->disp;
-
- /* Set evas image object size */
- evas_object_geometry_get(evaspixmapsink->eo, NULL, NULL, &evas_object_width, &evas_object_height);
- if (evaspixmapsink->use_origin_size || !evas_object_width || !evas_object_height) {
- pixmap_width = evaspixmapsink->video_width;
- pixmap_height = evaspixmapsink->video_height;
- GST_INFO_OBJECT (evaspixmapsink,"set size to media src size(%dx%d)", pixmap_width, pixmap_height);
- }
-
- g_mutex_lock (evaspixmapsink->x_lock);
- if (evaspixmapsink->use_origin_size || !evas_object_width || !evas_object_height) {
- XvQueryBestSize(dpy, evaspixmapsink->xcontext->xv_port_id,0,0,0, pixmap_width, pixmap_height, &xw, &xh);
- if (!evas_object_width || !evas_object_height) {
- evaspixmapsink->w = xw;
- evaspixmapsink->h = xh;
- } else {
- evaspixmapsink->w = evas_object_width;
- evaspixmapsink->h = evas_object_height;
- }
- GST_DEBUG_OBJECT (evaspixmapsink,"XvQueryBestSize : xv_port_id(%d), w(%d),h(%d) => xw(%d),xh(%d)", evaspixmapsink->xcontext->xv_port_id, pixmap_width, pixmap_height, xw, xh);
- } else {
- XvQueryBestSize(dpy, evaspixmapsink->xcontext->xv_port_id,0,0,0, evas_object_width, evas_object_height, &xw, &xh);
- GST_DEBUG_OBJECT (evaspixmapsink,"XvQueryBestSize : xv_port_id(%d), w(%d),h(%d) => xw(%d),xh(%d)", evaspixmapsink->xcontext->xv_port_id, evas_object_width, evas_object_height, xw, xh);
- evaspixmapsink->w = xw;
- evaspixmapsink->h = xh;
- }
- evas_object_image_size_set(evaspixmapsink->eo, evaspixmapsink->w, evaspixmapsink->h);
-
- /* create xpixmap structure */
- if (!evaspixmapsink->xpixmap) {
- /* xpixmap can be created in this function only */
- evaspixmapsink->xpixmap = g_new0 (GstXPixmap, 1);
- if(!evaspixmapsink->xpixmap) {
- GST_ERROR_OBJECT (evaspixmapsink,"xpixmap is not valid..");
- goto GO_OUT_OF_FUNC;
- }
- }
-
- /* create pixmap */
- if (!xw || !xh) {
- GST_WARNING_OBJECT (evaspixmapsink,"skip creating pixmap..xw(%d),xh(%d)",xw,xh);
- goto GO_OUT_OF_FUNC;
- } else {
- pixmap_id = XCreatePixmap(dpy, DefaultRootWindow(dpy), xw, xh, DefaultDepth(dpy, DefaultScreen(dpy)));
- if ( (int)pixmap_id == BadAlloc || (int)pixmap_id == BadDrawable || (int)pixmap_id == BadValue ) {
- GST_ERROR_OBJECT (evaspixmapsink,"pixmap allocation error..");
- goto GO_OUT_OF_FUNC;
- }
- GST_DEBUG_OBJECT (evaspixmapsink,"evas_object_width(%d),evas_object_height(%d),pixmap:%d,depth:%d",
- evas_object_width,evas_object_height,pixmap_id,DefaultDepth(dpy, DefaultScreen(dpy)));
- }
-
- if (evaspixmapsink->xpixmap->pixmap && pixmap_id != evaspixmapsink->xpixmap->pixmap) {
- /* If we reset another pixmap, do below */
- GST_DEBUG_OBJECT (evaspixmapsink,"destroy former pixmap(%d)",evaspixmapsink->xpixmap->pixmap);
- if (evaspixmapsink->eo) {
- evas_object_image_native_surface_set(evaspixmapsink->eo, NULL);
- }
- g_mutex_unlock (evaspixmapsink->x_lock);
- gst_evaspixmapsink_xpixmap_clear (evaspixmapsink, evaspixmapsink->xpixmap);
- g_mutex_lock (evaspixmapsink->x_lock);
- if(evaspixmapsink->xpixmap->pixmap) {
- XFreePixmap(evaspixmapsink->xcontext->disp, evaspixmapsink->xpixmap->pixmap);
- evaspixmapsink->xpixmap->pixmap = NULL;
- GST_DEBUG_OBJECT (evaspixmapsink,"Free pixmap");
- }
- XFreeGC (evaspixmapsink->xcontext->disp, evaspixmapsink->xpixmap->gc);
- XSync (evaspixmapsink->xcontext->disp, FALSE);
- }
-
- /* Set pixmap id and create GC */
- evaspixmapsink->xpixmap->pixmap = pixmap_id;
- evaspixmapsink->xpixmap->gc = XCreateGC(dpy, evaspixmapsink->xpixmap->pixmap, 0,0);
- XSetForeground(dpy, evaspixmapsink->xpixmap->gc,evaspixmapsink->xcontext->black);
- XFillRectangle(dpy, evaspixmapsink->xpixmap->pixmap, evaspixmapsink->xpixmap->gc, 0, 0, xw, xh);
- XSync(dpy, FALSE);
-
- /* Create XDamage */
- if (evaspixmapsink->damage) {
- GST_DEBUG_OBJECT (evaspixmapsink,"destroy former damage(%d)",evaspixmapsink->damage);
- XDamageDestroy(evaspixmapsink->xcontext->disp, evaspixmapsink->damage);
- evaspixmapsink->damage = NULL;
- }
- evaspixmapsink->damage = XDamageCreate (dpy, evaspixmapsink->xpixmap->pixmap, XDamageReportRawRectangles);
-
- /* Set flag for mapping evas object with xpixmap */
- evaspixmapsink->do_link = TRUE;
- ecore_pipe_write(evaspixmapsink->epipe, evaspixmapsink, sizeof(GstEvasPixmapSink));
-
- gst_evaspixmapsink_update_colorbalance (evaspixmapsink);
-
- g_mutex_unlock (evaspixmapsink->x_lock);
- g_mutex_unlock (evaspixmapsink->flow_lock);
-
- return TRUE;
-
-GO_OUT_OF_FUNC:
- g_mutex_unlock (evaspixmapsink->x_lock);
- g_mutex_unlock (evaspixmapsink->flow_lock);
- return FALSE;
-}
-
-static void
-gst_evaspixmapsink_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
-{
- GstEvasPixmapSink *evaspixmapsink;
- g_return_if_fail (GST_IS_EVASPIXMAPSINK (object));
- evaspixmapsink = GST_EVASPIXMAPSINK (object);
-
- Evas_Object *eo;
-
- switch (prop_id) {
- case PROP_HUE:
- evaspixmapsink->hue = g_value_get_int (value);
- evaspixmapsink->cb_changed = TRUE;
- gst_evaspixmapsink_update_colorbalance (evaspixmapsink);
- break;
- case PROP_CONTRAST:
- evaspixmapsink->contrast = g_value_get_int (value);
- evaspixmapsink->cb_changed = TRUE;
- gst_evaspixmapsink_update_colorbalance (evaspixmapsink);
- break;
- case PROP_BRIGHTNESS:
- evaspixmapsink->brightness = g_value_get_int (value);
- evaspixmapsink->cb_changed = TRUE;
- gst_evaspixmapsink_update_colorbalance (evaspixmapsink);
- break;
- case PROP_SATURATION:
- evaspixmapsink->saturation = g_value_get_int (value);
- evaspixmapsink->cb_changed = TRUE;
- gst_evaspixmapsink_update_colorbalance (evaspixmapsink);
- break;
- case PROP_DISPLAY:
- evaspixmapsink->display_name = g_strdup (g_value_get_string (value));
- break;
- case PROP_SYNCHRONOUS:
- evaspixmapsink->synchronous = g_value_get_boolean (value);
- if (evaspixmapsink->xcontext) {
- XSynchronize (evaspixmapsink->xcontext->disp, evaspixmapsink->synchronous);
- GST_DEBUG_OBJECT (evaspixmapsink,"XSynchronize called with %s", evaspixmapsink->synchronous ? "TRUE" : "FALSE");
- }
- break;
- case PROP_PIXEL_ASPECT_RATIO:
- g_free (evaspixmapsink->par);
- evaspixmapsink->par = g_new0 (GValue, 1);
- g_value_init (evaspixmapsink->par, GST_TYPE_FRACTION);
- if (!g_value_transform (value, evaspixmapsink->par)) {
- g_warning ("Could not transform string to aspect ratio");
- gst_value_set_fraction (evaspixmapsink->par, 1, 1);
- }
- GST_DEBUG_OBJECT (evaspixmapsink,"set PAR to %d/%d", gst_value_get_fraction_numerator (evaspixmapsink->par), gst_value_get_fraction_denominator (evaspixmapsink->par));
- break;
- case PROP_FORCE_ASPECT_RATIO:
- evaspixmapsink->keep_aspect = g_value_get_boolean (value);
- break;
- case PROP_DEVICE:
- evaspixmapsink->adaptor_no = atoi (g_value_get_string (value));
- break;
- case PROP_DOUBLE_BUFFER:
- evaspixmapsink->double_buffer = g_value_get_boolean (value);
- break;
- case PROP_AUTOPAINT_COLORKEY:
- evaspixmapsink->autopaint_colorkey = g_value_get_boolean (value);
- break;
- case PROP_COLORKEY:
- evaspixmapsink->colorkey = g_value_get_int (value);
- break;
- case PROP_PIXMAP_WIDTH:
- if (evaspixmapsink->xpixmap) {
- evaspixmapsink->xpixmap->width = g_value_get_uint64 (value);
- /* To do : code related to pixmap re-link */
- }
- break;
- case PROP_PIXMAP_HEIGHT:
- if (evaspixmapsink->xpixmap) {
- evaspixmapsink->xpixmap->height = g_value_get_uint64 (value);
- /* To do : code related to pixmap re-link */
- }
- break;
-#ifdef GST_EXT_XV_ENHANCEMENT
- case PROP_DISPLAY_GEOMETRY_METHOD:
- evaspixmapsink->display_geometry_method = g_value_get_enum (value);
- GST_INFO_OBJECT (evaspixmapsink,"Overlay geometry method update, display_geometry_method(%d)",evaspixmapsink->display_geometry_method);
- if( evaspixmapsink->display_geometry_method != DISP_GEO_METHOD_FULL_SCREEN &&
- evaspixmapsink->display_geometry_method != DISP_GEO_METHOD_CROPPED_FULL_SCREEN ) {
- if( evaspixmapsink->xcontext && evaspixmapsink->xpixmap ) {
- g_mutex_lock( evaspixmapsink->flow_lock );
- gst_evaspixmapsink_xpixmap_clear (evaspixmapsink, evaspixmapsink->xpixmap);
- g_mutex_unlock( evaspixmapsink->flow_lock );
- }
- }
- if (evaspixmapsink->xcontext) {
- gst_evaspixmap_buffer_put (evaspixmapsink, evaspixmapsink->evas_pixmap_buf);
- }
- break;
- case PROP_DST_ROI_X:
- evaspixmapsink->dst_roi.x = g_value_get_int (value);
- GST_INFO_OBJECT (evaspixmapsink, "ROI_X(%d)",evaspixmapsink->dst_roi.x );
- break;
- case PROP_DST_ROI_Y:
- evaspixmapsink->dst_roi.y = g_value_get_int (value);
- GST_INFO_OBJECT (evaspixmapsink, "ROI_Y(%d)",evaspixmapsink->dst_roi.y );
- break;
- case PROP_DST_ROI_W:
- evaspixmapsink->dst_roi.w = g_value_get_int (value);
- GST_INFO_OBJECT (evaspixmapsink, "ROI_W(%d)",evaspixmapsink->dst_roi.w );
- break;
- case PROP_DST_ROI_H:
- evaspixmapsink->dst_roi.h = g_value_get_int (value);
- GST_INFO_OBJECT (evaspixmapsink, "ROI_H(%d)",evaspixmapsink->dst_roi.h );
- break;
- case PROP_STOP_VIDEO:
- evaspixmapsink->stop_video = g_value_get_int (value);
- g_mutex_lock( evaspixmapsink->flow_lock );
- if( evaspixmapsink->stop_video ) {
- GST_INFO_OBJECT (evaspixmapsink, "XPixmap CLEAR when set video-stop property" );
- gst_evaspixmapsink_xpixmap_clear (evaspixmapsink, evaspixmapsink->xpixmap);
- }
- g_mutex_unlock( evaspixmapsink->flow_lock );
- break;
-#endif
- case PROP_EVAS_OBJECT:
- eo = g_value_get_pointer (value);
- if ( is_evas_image_object (eo)) {
- if (!evaspixmapsink->epipe) {
- evaspixmapsink->epipe = ecore_pipe_add (ecore_pipe_callback_handler, evaspixmapsink);
- if (!evaspixmapsink->epipe) {
- GST_ERROR_OBJECT (evaspixmapsink,"Cannot set evas-object property: ecore_pipe_add() failed");
- break;
- }
- }
- if (eo != evaspixmapsink->eo) {
- /* delete evas object callbacks registrated on a former evas image object */
- evas_object_event_callback_del (evaspixmapsink->eo, EVAS_CALLBACK_DEL, evas_callback_del_event);
- evas_object_event_callback_del (evaspixmapsink->eo, EVAS_CALLBACK_RESIZE, evas_callback_resize_event);
- if (evaspixmapsink->eo) {
- if (!gst_evaspixmapsink_xpixmap_link(evaspixmapsink)) {
- GST_WARNING_OBJECT (evaspixmapsink,"link evas image object with pixmap failed...");
- return;
- }
- }
- evaspixmapsink->eo = eo;
- /* add evas object callbacks on a new evas image object */
- evas_object_event_callback_add (evaspixmapsink->eo, EVAS_CALLBACK_DEL, evas_callback_del_event, evaspixmapsink);
- evas_object_event_callback_add (evaspixmapsink->eo, EVAS_CALLBACK_RESIZE, evas_callback_resize_event, evaspixmapsink);
- GST_INFO_OBJECT (evaspixmapsink,"Evas Image Object(%x) is set", evaspixmapsink->eo);
- }
- } else {
- GST_ERROR_OBJECT (evaspixmapsink,"Cannot set evas-object property: value is not an evas image object");
- }
- break;
- case PROP_VISIBLE:
- evaspixmapsink->visible = g_value_get_boolean (value);
- if (evaspixmapsink->eo) {
- if (!evaspixmapsink->visible) {
- if ( evaspixmapsink->xcontext && evaspixmapsink->xpixmap ) {
- g_mutex_lock( evaspixmapsink->flow_lock );
- gst_evaspixmapsink_xpixmap_clear (evaspixmapsink, evaspixmapsink->xpixmap);
- g_mutex_unlock( evaspixmapsink->flow_lock );
- }
- evas_object_hide(evaspixmapsink->eo);
- GST_INFO_OBJECT (evaspixmapsink,"object hide..");
- } else {
- evas_object_show(evaspixmapsink->eo);
- GST_INFO_OBJECT (evaspixmapsink,"object show..");
- }
- } else {
- GST_WARNING_OBJECT (evaspixmapsink,"evas image object was not set");
- }
- break;
- case PROP_ORIGIN_SIZE:
- evaspixmapsink->use_origin_size = g_value_get_boolean (value);
- GST_INFO_OBJECT (evaspixmapsink,"set origin-size (%d)",evaspixmapsink->use_origin_size);
- if (evaspixmapsink->former_origin_size != evaspixmapsink->use_origin_size) {
- if (!gst_evaspixmapsink_xpixmap_link(evaspixmapsink)) {
- GST_WARNING_OBJECT (evaspixmapsink,"link evas image object with pixmap failed...");
- }
- evaspixmapsink->former_origin_size = evaspixmapsink->use_origin_size;
- }
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static void
-gst_evaspixmapsink_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
-{
- GstEvasPixmapSink *evaspixmapsink;
-
- g_return_if_fail (GST_IS_EVASPIXMAPSINK (object));
-
- evaspixmapsink = GST_EVASPIXMAPSINK (object);
-
- switch (prop_id) {
- case PROP_HUE:
- g_value_set_int (value, evaspixmapsink->hue);
- break;
- case PROP_CONTRAST:
- g_value_set_int (value, evaspixmapsink->contrast);
- break;
- case PROP_BRIGHTNESS:
- g_value_set_int (value, evaspixmapsink->brightness);
- break;
- case PROP_SATURATION:
- g_value_set_int (value, evaspixmapsink->saturation);
- break;
- case PROP_DISPLAY:
- g_value_set_string (value, evaspixmapsink->display_name);
- break;
- case PROP_SYNCHRONOUS:
- g_value_set_boolean (value, evaspixmapsink->synchronous);
- break;
- case PROP_PIXEL_ASPECT_RATIO:
- if (evaspixmapsink->par) {
- if (!g_value_transform (evaspixmapsink->par, value)) {
- g_warning ("g_value_transform() failure");
- }
- }
- break;
- case PROP_FORCE_ASPECT_RATIO:
- g_value_set_boolean (value, evaspixmapsink->keep_aspect);
- break;
- case PROP_DEVICE:
- {
- char *adaptor_no_s = g_strdup_printf ("%u", evaspixmapsink->adaptor_no);
- g_value_set_string (value, adaptor_no_s);
- g_free (adaptor_no_s);
- break;
- }
- case PROP_DEVICE_NAME:
- if (evaspixmapsink->xcontext && evaspixmapsink->xcontext->adaptors) {
- g_value_set_string (value,
- evaspixmapsink->xcontext->adaptors[evaspixmapsink->adaptor_no]);
- } else {
- g_value_set_string (value, NULL);
- }
- break;
- case PROP_DOUBLE_BUFFER:
- g_value_set_boolean (value, evaspixmapsink->double_buffer);
- break;
- case PROP_AUTOPAINT_COLORKEY:
- g_value_set_boolean (value, evaspixmapsink->autopaint_colorkey);
- break;
- case PROP_COLORKEY:
- g_value_set_int (value, evaspixmapsink->colorkey);
- break;
- case PROP_PIXMAP_WIDTH:
- if (evaspixmapsink->xpixmap) {
- g_value_set_uint64 (value, evaspixmapsink->xpixmap->width);
- } else {
- g_value_set_uint64 (value, 0);
- }
- break;
- case PROP_PIXMAP_HEIGHT:
- if (evaspixmapsink->xpixmap) {
- g_value_set_uint64 (value, evaspixmapsink->xpixmap->height);
- } else {
- g_value_set_uint64 (value, 0);
- }
- break;
-#ifdef GST_EXT_XV_ENHANCEMENT
- case PROP_DISPLAY_GEOMETRY_METHOD:
- g_value_set_enum (value, evaspixmapsink->display_geometry_method);
- break;
- case PROP_DST_ROI_X:
- g_value_set_int (value, evaspixmapsink->dst_roi.x);
- break;
- case PROP_DST_ROI_Y:
- g_value_set_int (value, evaspixmapsink->dst_roi.y);
- break;
- case PROP_DST_ROI_W:
- g_value_set_int (value, evaspixmapsink->dst_roi.w);
- break;
- case PROP_DST_ROI_H:
- g_value_set_int (value, evaspixmapsink->dst_roi.h);
- break;
- case PROP_STOP_VIDEO:
- g_value_set_int (value, evaspixmapsink->stop_video);
- break;
-#endif
- case PROP_EVAS_OBJECT:
- g_value_set_pointer (value, evaspixmapsink->eo);
- break;
- case PROP_VISIBLE:
- g_value_set_boolean (value, evaspixmapsink->visible);
- break;
- case PROP_ORIGIN_SIZE:
- g_value_set_boolean (value, evaspixmapsink->use_origin_size);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static void
-gst_evaspixmapsink_reset (GstEvasPixmapSink *evaspixmapsink)
-{
- GST_DEBUG_OBJECT (evaspixmapsink,"[START]");
-
- GThread *thread;
- GST_OBJECT_LOCK (evaspixmapsink);
- evaspixmapsink->running = FALSE;
-
- /* grab thread and mark it as NULL */
- thread = evaspixmapsink->event_thread;
- evaspixmapsink->event_thread = NULL;
- GST_OBJECT_UNLOCK (evaspixmapsink);
-
- /* Wait for our event thread to finish before we clean up our stuff. */
- if (thread) {
- g_thread_join (thread);
- }
-
- if(evaspixmapsink->damage) {
- XDamageDestroy(evaspixmapsink->xcontext->disp, evaspixmapsink->damage);
- evaspixmapsink->damage = NULL;
- }
- if(evaspixmapsink->handler) {
- ecore_event_handler_del (evaspixmapsink->handler);
- evaspixmapsink->handler = NULL;
- }
-
- evas_object_event_callback_del (evaspixmapsink->eo, EVAS_CALLBACK_RESIZE, evas_callback_resize_event);
- evas_object_event_callback_del (evaspixmapsink->eo, EVAS_CALLBACK_DEL, evas_callback_del_event);
-
- if (evaspixmapsink->evas_pixmap_buf) {
- g_boxed_free(GST_TYPE_EVASPIXMAP_BUFFER, evaspixmapsink->evas_pixmap_buf);
- evaspixmapsink->evas_pixmap_buf = NULL;
- }
- if (evaspixmapsink->xpixmap) {
- gst_evaspixmapsink_xpixmap_clear (evaspixmapsink, evaspixmapsink->xpixmap);
- gst_evaspixmapsink_xpixmap_destroy (evaspixmapsink, evaspixmapsink->xpixmap);
- evaspixmapsink->xpixmap = NULL;
- if (evaspixmapsink->eo) {
- evas_object_image_native_surface_set(evaspixmapsink->eo, NULL);
- evaspixmapsink->eo = NULL;
- }
- }
- evaspixmapsink->render_rect.x = evaspixmapsink->render_rect.y =
- evaspixmapsink->render_rect.w = evaspixmapsink->render_rect.h = 0;
- evaspixmapsink->have_render_rect = FALSE;
-
- gst_evaspixmapsink_xcontext_clear (evaspixmapsink);
-
- GST_DEBUG_OBJECT (evaspixmapsink,"[END]");
-}
-
-/* Finalize is called only once, dispose can be called multiple times.
- * We use mutexes and don't reset stuff to NULL here so let's register
- * as a finalize. */
-static void
-gst_evaspixmapsink_finalize (GObject *object)
-{
- GstEvasPixmapSink *evaspixmapsink;
- evaspixmapsink = GST_EVASPIXMAPSINK (object);
- GST_DEBUG_OBJECT (evaspixmapsink,"[START]");
-
- if (evaspixmapsink->display_name) {
- g_free (evaspixmapsink->display_name);
- evaspixmapsink->display_name = NULL;
- }
- if (evaspixmapsink->par) {
- g_free (evaspixmapsink->par);
- evaspixmapsink->par = NULL;
- }
- if (evaspixmapsink->x_lock) {
- g_mutex_free (evaspixmapsink->x_lock);
- evaspixmapsink->x_lock = NULL;
- }
- if (evaspixmapsink->flow_lock) {
- g_mutex_free (evaspixmapsink->flow_lock);
- evaspixmapsink->flow_lock = NULL;
- }
- if (evaspixmapsink->epipe) {
- ecore_pipe_del (evaspixmapsink->epipe);
- evaspixmapsink->epipe = NULL;
- }
-
- GST_DEBUG_OBJECT (evaspixmapsink,"[END]");
-
- G_OBJECT_CLASS (parent_class)->finalize (object);
-
-}
-
-static void
-gst_evaspixmapsink_init (GstEvasPixmapSink *evaspixmapsink)
-{
- evaspixmapsink->display_name = NULL;
- evaspixmapsink->adaptor_no = 0;
- evaspixmapsink->xcontext = NULL;
- evaspixmapsink->xpixmap = NULL;
- evaspixmapsink->evas_pixmap_buf = NULL;
-
- evaspixmapsink->hue = evaspixmapsink->saturation = 0;
- evaspixmapsink->contrast = evaspixmapsink->brightness = 0;
- evaspixmapsink->cb_changed = FALSE;
-
- evaspixmapsink->fps_n = 0;
- evaspixmapsink->fps_d = 0;
- evaspixmapsink->video_width = 0;
- evaspixmapsink->video_height = 0;
-
- evaspixmapsink->x_lock = g_mutex_new ();
- evaspixmapsink->flow_lock = g_mutex_new ();
-
- evaspixmapsink->synchronous = FALSE;
- evaspixmapsink->double_buffer = TRUE;
- evaspixmapsink->keep_aspect = FALSE;
- evaspixmapsink->par = NULL;
- evaspixmapsink->autopaint_colorkey = TRUE;
- evaspixmapsink->running = FALSE;
-
- /* on 16bit displays this becomes r,g,b = 1,2,3
- * on 24bit displays this becomes r,g,b = 8,8,16
- * as a port atom value
- */
- evaspixmapsink->colorkey = (8 << 16) | (8 << 8) | 16;
-
-#ifdef GST_EXT_XV_ENHANCEMENT
- evaspixmapsink->display_geometry_method = DEF_DISPLAY_GEOMETRY_METHOD;
- evaspixmapsink->dst_roi.x = 0;
- evaspixmapsink->dst_roi.y = 0;
- evaspixmapsink->dst_roi.w = 0;
- evaspixmapsink->dst_roi.h = 0;
- evaspixmapsink->scr_w = 0;
- evaspixmapsink->scr_h = 0;
- evaspixmapsink->aligned_width = 0;
- evaspixmapsink->aligned_height = 0;
-#endif
- evaspixmapsink->stop_video = FALSE;
- evaspixmapsink->eo = NULL;
- evaspixmapsink->epipe = NULL;
- evaspixmapsink->do_link = FALSE;
- evaspixmapsink->visible = TRUE;
- evaspixmapsink->use_origin_size = FALSE;
- evaspixmapsink->former_origin_size = FALSE;
-
- }
-
-static void
-gst_evaspixmapsink_base_init (gpointer g_class)
-{
-}
-
-static void
-gst_evaspixmapsink_class_init (GstEvasPixmapSinkClass *klass)
-{
- GObjectClass *gobject_class;
- GstElementClass *gstelement_class;
- GstBaseSinkClass *gstbasesink_class;
- GstVideoSinkClass *videosink_class;
-
- gobject_class = (GObjectClass *) klass;
- gstelement_class = (GstElementClass *) klass;
- gstbasesink_class = (GstBaseSinkClass *) klass;
- videosink_class = (GstVideoSinkClass *) klass;
-
- parent_class = g_type_class_peek_parent (klass);
-
- gobject_class->set_property = gst_evaspixmapsink_set_property;
- gobject_class->get_property = gst_evaspixmapsink_get_property;
-
- g_object_class_install_property (gobject_class, PROP_CONTRAST,
- g_param_spec_int ("contrast", "Contrast", "The contrast of the video",
- -1000, 1000, 0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
- g_object_class_install_property (gobject_class, PROP_BRIGHTNESS,
- g_param_spec_int ("brightness", "Brightness",
- "The brightness of the video", -1000, 1000, 0,
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
- g_object_class_install_property (gobject_class, PROP_HUE,
- g_param_spec_int ("hue", "Hue", "The hue of the video", -1000, 1000, 0,
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
- g_object_class_install_property (gobject_class, PROP_SATURATION,
- g_param_spec_int ("saturation", "Saturation",
- "The saturation of the video", -1000, 1000, 0,
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
- g_object_class_install_property (gobject_class, PROP_DISPLAY,
- g_param_spec_string ("display", "Display", "X Display name", NULL,
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
- g_object_class_install_property (gobject_class, PROP_SYNCHRONOUS,
- g_param_spec_boolean ("synchronous", "Synchronous",
- "When enabled, runs "
- "the X display in synchronous mode. (used only for debugging)", FALSE,
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
- g_object_class_install_property (gobject_class, PROP_PIXEL_ASPECT_RATIO,
- g_param_spec_string ("pixel-aspect-ratio", "Pixel Aspect Ratio",
- "The pixel aspect ratio of the device", "1/1",
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
- g_object_class_install_property (gobject_class, PROP_FORCE_ASPECT_RATIO,
- g_param_spec_boolean ("force-aspect-ratio", "Force aspect ratio",
- "When enabled, scaling will respect original aspect ratio", FALSE,
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
- g_object_class_install_property (gobject_class, PROP_DEVICE,
- g_param_spec_string ("device", "Adaptor number",
- "The number of the video adaptor", "0",
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
- g_object_class_install_property (gobject_class, PROP_DEVICE_NAME,
- g_param_spec_string ("device-name", "Adaptor name",
- "The name of the video adaptor", NULL,
- G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
-
- /**
- * GstEvasPixmapSink:double-buffer
- *
- * Whether to double-buffer the output.
- *
- * Since: 0.10.14
- */
- g_object_class_install_property (gobject_class, PROP_DOUBLE_BUFFER,
- g_param_spec_boolean ("double-buffer", "Double-buffer",
- "Whether to double-buffer the output", TRUE,
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
- /**
- * GstEvasPixmapSink:autopaint-colorkey
- *
- * Whether to autofill overlay with colorkey
- *
- * Since: 0.10.21
- */
- g_object_class_install_property (gobject_class, PROP_AUTOPAINT_COLORKEY,
- g_param_spec_boolean ("autopaint-colorkey", "Autofill with colorkey",
- "Whether to autofill overlay with colorkey", TRUE,
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
- /**
- * GstEvasPixmapSink:colorkey
- *
- * Color to use for the overlay mask.
- *
- * Since: 0.10.21
- */
- g_object_class_install_property (gobject_class, PROP_COLORKEY,
- g_param_spec_int ("colorkey", "Colorkey",
- "Color to use for the overlay mask", G_MININT, G_MAXINT, 0,
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
-
- /**
- * GstEvasPixmapSink:pixmap-width
- *
- * Actual width of the pixmap.
- */
- g_object_class_install_property (gobject_class, PROP_PIXMAP_WIDTH,
- g_param_spec_uint64 ("pixmap-width", "pixmap-width", "Width of the pixmap", 0, G_MAXUINT64, 0, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
-
- /**
- * GstEvasPixmapSink:pixmap-height
- *
- * Actual height of the pixmap.
- */
- g_object_class_install_property (gobject_class, PROP_PIXMAP_HEIGHT,
- g_param_spec_uint64 ("pixmap-height", "pixmap-height", "Height of the pixmap", 0, G_MAXUINT64, 0, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
-
-#ifdef GST_EXT_XV_ENHANCEMENT
- /**
- * GstEvasPixmapSink:display-geometry-method
- *
- * Display geometrical method setting
- */
- g_object_class_install_property(gobject_class, PROP_DISPLAY_GEOMETRY_METHOD,
- g_param_spec_enum("display-geometry-method", "Display geometry method",
- "Geometrical method for display",
- GST_TYPE_EVASPIXMAPSINK_DISPLAY_GEOMETRY_METHOD, DEF_DISPLAY_GEOMETRY_METHOD,
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
-
- /**
- * GstEvasPixmapSink:dst-roi-x
- *
- * X value of Destination ROI
- */
- g_object_class_install_property (gobject_class, PROP_DST_ROI_X,
- g_param_spec_int ("dst-roi-x", "Dst-ROI-X",
- "X value of Destination ROI(only effective \"CUSTOM_ROI\")", 0, XV_SCREEN_SIZE_WIDTH, 0,
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
-
- /**
- * GstEvasPixmapSink:dst-roi-y
- *
- * Y value of Destination ROI
- */
- g_object_class_install_property (gobject_class, PROP_DST_ROI_Y,
- g_param_spec_int ("dst-roi-y", "Dst-ROI-Y",
- "Y value of Destination ROI(only effective \"CUSTOM_ROI\")", 0, XV_SCREEN_SIZE_HEIGHT, 0,
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
-
- /**
- * GstEvasPixmapSink:dst-roi-w
- *
- * W value of Destination ROI
- */
- g_object_class_install_property (gobject_class, PROP_DST_ROI_W,
- g_param_spec_int ("dst-roi-w", "Dst-ROI-W",
- "W value of Destination ROI(only effective \"CUSTOM_ROI\")", 0, XV_SCREEN_SIZE_WIDTH, 0,
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
-
- /**
- * GstEvasPixmapSink:dst-roi-h
- *
- * H value of Destination ROI
- */
- g_object_class_install_property (gobject_class, PROP_DST_ROI_H,
- g_param_spec_int ("dst-roi-h", "Dst-ROI-H",
- "H value of Destination ROI(only effective \"CUSTOM_ROI\")", 0, XV_SCREEN_SIZE_HEIGHT, 0,
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
-
- /**
- * GstEvasPixmapSink:stop-video
- *
- * Stop video for releasing video source buffer
- */
- g_object_class_install_property (gobject_class, PROP_STOP_VIDEO,
- g_param_spec_int ("stop-video", "Stop-Video", "Stop video for releasing video source buffer", 0, 1, 0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
-#endif
-
- /**
- * GstEvasPixmapSink:evas-object
- *
- * Evas image object for rendering
- */
- g_object_class_install_property (gobject_class, PROP_EVAS_OBJECT,
- g_param_spec_pointer ("evas-object", "Destination Evas Object", "Destination evas image object", G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
-
- /**
- * GstEvasPixmapSink:visible
- *
- * visible setting for a evas image object
- */
- g_object_class_install_property (gobject_class, PROP_VISIBLE,
- g_param_spec_boolean ("visible", "Visible", "When setting it false, evas image object does not show", TRUE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
-
- /**
- * GstEvasPixmapSink:origin-size
- *
- * Set pixmap size with media source's width and height
- */
- g_object_class_install_property (gobject_class, PROP_ORIGIN_SIZE,
- g_param_spec_boolean ("origin-size", "Origin-Size", "When setting it true, pixmap will be created with media source's width and height", FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
-
- gobject_class->finalize = gst_evaspixmapsink_finalize;
-
- gstelement_class->change_state = GST_DEBUG_FUNCPTR (gst_evaspixmapsink_change_state);
- gst_element_class_set_details_simple (gstelement_class,
- "EvasPixmapSink", "Sink/Video",
- "evas image object videosink based on Xv extension", "Sangchul Lee <sc11.lee@samsung.com>");
-
- gst_element_class_add_pad_template (gstelement_class,
- gst_static_pad_template_get (&gst_evaspixmapsink_sink_template_factory));
- gstbasesink_class->get_caps = GST_DEBUG_FUNCPTR (gst_evaspixmapsink_getcaps);
- gstbasesink_class->set_caps = GST_DEBUG_FUNCPTR (gst_evaspixmapsink_setcaps);
- gstbasesink_class->get_times = GST_DEBUG_FUNCPTR (gst_evaspixmapsink_get_times);
- gstbasesink_class->event = GST_DEBUG_FUNCPTR (gst_evaspixmapsink_event);
- videosink_class->show_frame = GST_DEBUG_FUNCPTR (gst_evaspixmapsink_show_frame);
-}
-
-/* Object typing & Creation */
-
-static gboolean
-plugin_init (GstPlugin *plugin)
-{
- if (!gst_element_register (plugin, "evaspixmapsink", GST_RANK_NONE, GST_TYPE_EVASPIXMAPSINK)) {
- return FALSE;
- }
- GST_DEBUG_CATEGORY_INIT (gst_debug_evaspixmapsink, "evaspixmapsink", 0, "evaspixmapsink element");
- GST_DEBUG_CATEGORY_GET (GST_CAT_PERFORMANCE, "GST_PERFORMANCE");
-
- return TRUE;
-}
-
-GST_PLUGIN_DEFINE (GST_VERSION_MAJOR, GST_VERSION_MINOR,
- evaspixmapsink,"Evas image object render plugin using Xv extension", plugin_init,
- VERSION, GST_LICENSE, GST_PACKAGE_NAME, GST_PACKAGE_ORIGIN)
+++ /dev/null
-/*
- * EvasPixmapSink
- *
- * Copyright (c) 2000 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
- *
- * Contact: Sangchul Lee <sc11.lee@samsung.com>
- *
- * This library is free software; you can redistribute it and/or modify it under
- * the terms of the GNU Lesser General Public License as published by the
- * Free Software Foundation; either version 2.1 of the License, or (at your option)
- * any later version.
- *
- * This library is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
- * License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this library; if not, write to the Free Software Foundation, Inc., 51
- * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- */
-
-#ifndef __GST_EVASPIXMAPSINK_H__
-#define __GST_EVASPIXMAPSINK_H__
-
-#include <gst/video/gstvideosink.h>
-
-#ifdef HAVE_XSHM
-#include <sys/types.h>
-#include <sys/ipc.h>
-#include <sys/shm.h>
-#endif /* HAVE_XSHM */
-
-#include <X11/Xlib.h>
-#include <X11/Xutil.h>
-
-#ifdef HAVE_XSHM
-#include <X11/extensions/XShm.h>
-#endif /* HAVE_XSHM */
-
-#include <X11/extensions/Xv.h>
-#include <X11/extensions/Xvlib.h>
-#include <X11/extensions/Xdamage.h>
-#include <X11/extensions/damagewire.h>
-#ifdef GST_EXT_XV_ENHANCEMENT
-#include <X11/Xatom.h>
-#include <stdio.h>
-#endif
-
-#include <Evas.h>
-#include <Ecore.h>
-#include <Ecore_X.h>
-
-#include <string.h>
-#include <math.h>
-#include <stdlib.h>
-
-#define MAX_PLANE_NUM 3
-#define MAX_BUFFER_NUM 20
-#define MAX_GEM_BUFFER_NUM (MAX_PLANE_NUM * MAX_BUFFER_NUM)
-typedef struct _gem_info_t {
- int dmabuf_fd;
- unsigned int gem_handle;
- unsigned int gem_name;
-} gem_info_t;
-
-
-G_BEGIN_DECLS
-
-#define GST_TYPE_EVASPIXMAPSINK \
- (gst_evaspixmapsink_get_type())
-#define GST_EVASPIXMAPSINK(obj) \
- (G_TYPE_CHECK_INSTANCE_CAST((obj), GST_TYPE_EVASPIXMAPSINK, GstEvasPixmapSink))
-#define GST_EVASPIXMAPSINK_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_CAST((klass), GST_TYPE_EVASPIXMAPSINK, GstEvasPixmapSinkClass))
-#define GST_IS_EVASPIXMAPSINK(obj) \
- (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_TYPE_EVASPIXMAPSINK))
-#define GST_IS_EVASPIXMAPSINK_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_TYPE((klass), GST_TYPE_EVASPIXMAPSINK))
-
-#ifdef GST_EXT_XV_ENHANCEMENT
-#define XV_SCREEN_SIZE_WIDTH 4096
-#define XV_SCREEN_SIZE_HEIGHT 4096
-#endif /* GST_EXT_XV_ENHANCEMENT */
-#define MARGIN_OF_ERROR 0.005
-
-typedef struct _GstXContext GstXContext;
-typedef struct _GstXPixmap GstXPixmap;
-typedef struct _GstEvasPixmapFormat GstEvasPixmapFormat;
-typedef struct _GstEvasPixmapBuffer GstEvasPixmapBuffer;
-typedef struct _GstEvasPixmapBufferClass GstEvasPixmapBufferClass;
-typedef struct _GstEvasPixmapSink GstEvasPixmapSink;
-typedef struct _GstEvasPixmapSinkClass GstEvasPixmapSinkClass;
-
-/*
- * GstXContext:
- * @disp: the X11 Display of this context
- * @screen: the default Screen of Display @disp
- * @screen_num: the Screen number of @screen
- * @visual: the default Visual of Screen @screen
- * @root: the root Window of Display @disp
- * @white: the value of a white pixel on Screen @screen
- * @black: the value of a black pixel on Screen @screen
- * @depth: the color depth of Display @disp
- * @bpp: the number of bits per pixel on Display @disp
- * @endianness: the endianness of image bytes on Display @disp
- * @width: the width in pixels of Display @disp
- * @height: the height in pixels of Display @disp
- * @widthmm: the width in millimeters of Display @disp
- * @heightmm: the height in millimeters of Display @disp
- * @par: the pixel aspect ratio calculated from @width, @widthmm and @height,
- * @heightmm ratio
- * @use_xshm: used to known wether of not XShm extension is usable or not even
- * if the Extension is present
- * @xv_port_id: the XVideo port ID
- * @im_format: used to store at least a valid format for XShm calls checks
- * @formats_list: list of supported image formats on @xv_port_id
- * @channels_list: list of #GstColorBalanceChannels
- * @caps: the #GstCaps that Display @disp can accept
- *
- * Structure used to store various informations collected/calculated for a
- * Display.
- */
-struct _GstXContext {
- Display *disp;
-
- Screen *screen;
- gint screen_num;
-
- Visual *visual;
-
- Window root;
-
- gulong white, black;
-
- gint depth;
- gint bpp;
- gint endianness;
-
- gint width, height;
- gint widthmm, heightmm;
- GValue *par; /* calculated pixel aspect ratio */
-
- gboolean use_xshm;
-
- XvPortID xv_port_id;
- guint nb_adaptors;
- gchar ** adaptors;
- guint32 im_format;
-
- GList *formats_list;
- GList *channels_list;
-
- GstCaps *caps;
-};
-
-/*
- * GstXPixmap:
- * @pixmap: the pixmap ID of this X11 pixmap
- * @width: the width in pixels of Pixmap @pixmap
- * @height: the height in pixels of Pixmap @pixmap
- * @gc: the Graphical Context of Pixmap @pixmap
- *
- * Structure used to store informations about a Pixmap.
- */
-struct _GstXPixmap {
- Pixmap pixmap;
-#ifdef GST_EXT_XV_ENHANCEMENT
- gint x, y;
-#endif
- gint width, height;
- GC gc;
-};
-
-/**
- * GstEvasPixmapFormat:
- * @format: the image format
- * @caps: generated #GstCaps for this image format
- *
- * Structure storing image format to #GstCaps association.
- */
-struct _GstEvasPixmapFormat {
- guint32 format;
- GstCaps *caps;
-};
-
-/**
- * GstEvasPixmapBuffer:
- * @evaspixmapsink: a reference to our #GstEvasPixmapSink
- * @xvimage: the XvImage of this buffer
- * @width: the width in pixels of XvImage @xvimage
- * @height: the height in pixels of XvImage @xvimage
- * @im_format: the image format of XvImage @xvimage
- * @size: the size in bytes of XvImage @xvimage
- *
- * Subclass of #GstBuffer containing additional information about an XvImage.
- */
-struct _GstEvasPixmapBuffer {
- GstBuffer* buffer;
-
- /* Reference to the evaspixmapsink we belong to */
- GstEvasPixmapSink *evaspixmapsink;
- XvImage *xvimage;
-
-#ifdef HAVE_XSHM
- XShmSegmentInfo SHMInfo;
-#endif /* HAVE_XSHM */
-
- gint width, height;
- guint32 im_format;
- size_t size;
-};
-
-/**
- * GstEvasPixmapSink:
- * @display_name: the name of the Display we want to render to
- * @xcontext: our instance's #GstXContext
- * @xpixmap: the #GstXPixmap we are rendering to
- * @fps_n: the framerate fraction numerator
- * @fps_d: the framerate fraction denominator
- * @x_lock: used to protect X calls as we are not using the XLib in threaded
- * mode
- * @flow_lock: used to protect data flow routines from external calls such as
- * methods from the #GstXOverlay interface
- * @par: used to override calculated pixel aspect ratio from @xcontext
- * @synchronous: used to store if XSynchronous should be used or not (for
- * debugging purpose only)
- * @keep_aspect: used to remember if reverse negotiation scaling should respect
- * aspect ratio
- * @brightness: used to store the user settings for color balance brightness
- * @contrast: used to store the user settings for color balance contrast
- * @hue: used to store the user settings for color balance hue
- * @saturation: used to store the user settings for color balance saturation
- * @cb_changed: used to store if the color balance settings where changed
- * @video_width: the width of incoming video frames in pixels
- * @video_height: the height of incoming video frames in pixels
- *
- * The #GstEvasPixmapSink data structure.
- */
-struct _GstEvasPixmapSink {
- /* Our element stuff */
- GstVideoSink videosink;
-
- char *display_name;
- guint adaptor_no;
-
- GstXContext *xcontext;
- GstXPixmap *xpixmap;
- GstEvasPixmapBuffer *evas_pixmap_buf;
-
- GThread *event_thread;
- gboolean running;
-
- gint fps_n;
- gint fps_d;
-
- GMutex *x_lock;
- GMutex *flow_lock;
-
- /* object-set pixel aspect ratio */
- GValue *par;
-
- gboolean synchronous;
- gboolean double_buffer;
- gboolean keep_aspect;
-
- gint brightness;
- gint contrast;
- gint hue;
- gint saturation;
- gboolean cb_changed;
-
- /* size of incoming video, used as the size for XvImage */
- guint video_width, video_height;
-
- /* display sizes, used for clipping the image */
- gint disp_x, disp_y;
- gint disp_width, disp_height;
-
- /* port attributes */
- gboolean autopaint_colorkey;
- gint colorkey;
-
- /* port features */
- gboolean have_autopaint_colorkey;
- gboolean have_colorkey;
- gboolean have_double_buffer;
-
- /* target video rectagle */
- GstVideoRectangle render_rect;
- gboolean have_render_rect;
-
-#ifdef GST_EXT_XV_ENHANCEMENT
- /* display */
- guint display_geometry_method;
- GstVideoRectangle dst_roi;
- guint scr_w, scr_h;
- /* needed if fourcc is one if S series */
- guint aligned_width;
- guint aligned_height;
- GstCaps *negotiated_caps;
-#endif
- gboolean stop_video;
-
- /* evas object */
- Evas_Object *eo;
- Evas_Coord w;
- Evas_Coord h;
- gboolean visible;
-
- /* pixmap */
- gboolean do_link;
- gboolean use_origin_size;
- gboolean former_origin_size;
-
- /* damage event */
- Damage damage;
- int damage_case;
- Ecore_Event_Handler *handler;
- Ecore_Pipe *epipe;
-
- gint drm_fd;
- gem_info_t gem_info[MAX_GEM_BUFFER_NUM];
-};
-
-#ifdef GST_EXT_XV_ENHANCEMENT
-/* max plane count *********************************************************/
-#define MPLANE_IMGB_MAX_COUNT (4)
-
-/* image buffer definition ***************************************************
-
- +------------------------------------------+ ---
- | | ^
- | uaddr[], index[] | |
- | +---------------------------+ --- | |
- | | | ^ | |
- | |<-------- width[] -------->| | | |
- | | | | | |
- | | | |
- | | |height[]|elevation[]
- | | | |
- | | | | | |
- | | | | | |
- | | | v | |
- | +---------------------------+ --- | |
- | | v
- +------------------------------------------+ ---
-
- |<----------------- stride[] ------------------>|
-*/
-typedef struct _GstMultiPlaneImageBuffer GstMultiPlaneImageBuffer;
-struct _GstMultiPlaneImageBuffer
-{
- GstBuffer buffer;
-
- /* width of each image plane */
- gint width[MPLANE_IMGB_MAX_COUNT];
- /* height of each image plane */
- gint height[MPLANE_IMGB_MAX_COUNT];
- /* stride of each image plane */
- gint stride[MPLANE_IMGB_MAX_COUNT];
- /* elevation of each image plane */
- gint elevation[MPLANE_IMGB_MAX_COUNT];
- /* user space address of each image plane */
- gpointer uaddr[MPLANE_IMGB_MAX_COUNT];
- /* Index of real address of each image plane, if needs */
- gpointer index[MPLANE_IMGB_MAX_COUNT];
- /* left postion, if needs */
- gint x;
- /* top position, if needs */
- gint y;
- /* to align memory */
- gint __dummy2;
- /* arbitrary data */
- gint data[16];
-};
-#endif /* GST_EXT_XV_ENHANCEMENT */
-
-struct _GstEvasPixmapSinkClass {
- GstVideoSinkClass parent_class;
-};
-
-GType gst_evaspixmapsink_get_type(void);
-
-G_END_DECLS
-
-#endif /* __GST_EVASPIXMAPSINK_H__ */
+++ /dev/null
-/* */
-/* File name : xv_types.h */
-/* Author : YoungHoon Jung (yhoon.jung@samsung.com) */
-/* Protocol Version : 1.0.1 (Dec 16th 2009) */
-/* This file is for describing Xv APIs' buffer encoding method. */
-/* */
-
-#define XV_PUTIMAGE_HEADER 0xDEADCD01
-#define XV_PUTIMAGE_VERSION 0x00010001
-
-/* Return Values */
-#define XV_OK 0
-#define XV_HEADER_ERROR -1
-#define XV_VERSION_MISMATCH -2
-
-/* Video Mode */
-#define VIDEO_MODE_TV_LCD 1
-#define VIDEO_MODE_TVONLY 2
-#define VIDEO_MODE_LCDONLY 3
-#define VIDEO_MODE_TVCAPTION 4
-
-/* Buffer Type */
-#define XV_BUF_TYPE_DMABUF 0
-#define XV_BUF_TYPE_LEGACY 1
-
-/* Data structure for XvPutImage / XvShmPutImage */
-typedef struct {
- unsigned int _header; /* for internal use only */
- unsigned int _version; /* for internal use only */
-
- unsigned int YBuf;
- unsigned int CbBuf;
- unsigned int CrBuf;
- unsigned int BufType;
-} XV_PUTIMAGE_DATA, * XV_PUTIMAGE_DATA_PTR;
-
-static void XV_PUTIMAGE_INIT_DATA(XV_PUTIMAGE_DATA_PTR data)
-{
- data->_header = XV_PUTIMAGE_HEADER;
- data->_version = XV_PUTIMAGE_VERSION;
-}
%configure \
%if %{with x}
--disable-waylandsrc\
-# --disable-waylandsink\
%else
--disable-xvimagesrc\
%endif
+++ /dev/null
-SUBDIRS = src
+++ /dev/null
-plugin_LTLIBRARIES = libgstwaylandsink.la
-
-libgstwaylandsink_la_SOURCES = \
- gstwaylandsink.c \
- waylandpool.c \
- wldisplay.c \
- wlwindow.c \
- wlvideoformat.c \
- scaler-protocol.c \
- tizen-wlvideoformat.c
-
-libgstwaylandsink_la_CFLAGS = $(GST_CFLAGS) $(GST_PLUGINS_BASE_CFLAGS) \
- $(WAYLAND_CFLAGS) $(GST_PLUGINS_BAD_CFLAGS) $(DRM_CFLAGS) $(TBM_CFLAGS) $(MMCOMMON_CFLAGS) \
- $(GST_WAYLAND_CFLAGS)
-libgstwaylandsink_la_LIBADD = \
- $(GST_PLUGINS_BASE_LIBS) \
- -lgstvideo-$(GST_MAJORMINOR) \
- $(WAYLAND_LIBS) $(DRM_LIBS) $(TBM_LIBS) $(GST_WAYLAND_LIBS)
-libgstwaylandsink_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
-libgstwaylandsink_la_LIBTOOLFLAGS = $(GST_PLUGIN_LIBTOOLFLAGS)
-
-noinst_HEADERS = \
- gstwaylandsink.h \
- waylandpool.h \
- wldisplay.h \
- wlwindow.h \
- wlvideoformat.h \
- scaler-client-protocol.h \
- tizen-wlvideoformat.h
-
-EXTRA_DIST = scaler.xml
-CLEANFILES = scaler-protocol.c scaler-client-protocol.h
-
-%-protocol.c : %.xml
- $(wayland_scanner) code < $< > $@
-
-%-client-protocol.h : %.xml
- $(wayland_scanner) client-header < $< > $@
-
-gstwaylandsink.c: scaler-client-protocol.h
-
-waylandpool.c: scaler-client-protocol.h
-
-wldisplay.c: scaler-client-protocol.h
-
-wlwindow.c: scaler-client-protocol.h
+++ /dev/null
-/* GStreamer Wayland video sink
- *
- * Copyright (C) 2011 Intel Corporation
- * Copyright (C) 2011 Sreerenj Balachandran <sreerenj.balachandran@intel.com>
- * Copyright (C) 2012 Wim Taymans <wim.taymans@gmail.com>
- * Copyright (C) 2014 Collabora Ltd.
- *
- * 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., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301 USA.
- */
-
-/**
- * SECTION:element-waylandsink
- *
- * The waylandsink is creating its own window and render the decoded video frames to that.
- * Setup the Wayland environment as described in
- * <ulink url="http://wayland.freedesktop.org/building.html">Wayland</ulink> home page.
- * The current implementaion is based on weston compositor.
- *
- * <refsect2>
- * <title>Example pipelines</title>
- * |[
- * gst-launch -v videotestsrc ! waylandsink
- * ]| test the video rendering in wayland
- * </refsect2>
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include "gstwaylandsink.h"
-#ifdef GST_WLSINK_ENHANCEMENT
-#include <mm_types.h>
-#include "tizen-wlvideoformat.h"
-#else
-#include "wlvideoformat.h"
-#endif
-#include "waylandpool.h"
-
-#include <gst/wayland/wayland.h>
-#include <gst/video/videooverlay.h>
-
-#ifdef GST_WLSINK_ENHANCEMENT
-#define GST_TYPE_WAYLANDSINK_DISPLAY_GEOMETRY_METHOD (gst_waylandsink_display_geometry_method_get_type())
-#define GST_TYPE_WAYLANDSINK_ROTATE_ANGLE (gst_waylandsink_rotate_angle_get_type())
-#define GST_TYPE_WAYLANDSINK_FLIP (gst_waylandsink_flip_get_type())
-
-static GType
-gst_waylandsink_rotate_angle_get_type (void)
-{
- static GType waylandsink_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 (!waylandsink_rotate_angle_type) {
- waylandsink_rotate_angle_type =
- g_enum_register_static ("GstWaylandSinkRotateAngleType",
- rotate_angle_type);
- }
-
- return waylandsink_rotate_angle_type;
-}
-
-
-static GType
-gst_waylandsink_display_geometry_method_get_type (void)
-{
- static GType waylandsink_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, NULL, NULL},
- };
-
- if (!waylandsink_display_geometry_method_type) {
- waylandsink_display_geometry_method_type =
- g_enum_register_static ("GstWaylandSinkDisplayGeometryMethodType",
- display_geometry_method_type);
- }
- return waylandsink_display_geometry_method_type;
-}
-
-static GType
-gst_waylandsink_flip_get_type (void)
-{
- static GType waylandsink_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 (!waylandsink_flip_type) {
- waylandsink_flip_type =
- g_enum_register_static ("GstWaylandSinkFlipType", flip_type);
- }
-
- return waylandsink_flip_type;
-}
-
-#endif
-
-
-/* signals */
-enum
-{
- SIGNAL_0,
- LAST_SIGNAL
-};
-
-/* Properties */
-enum
-{
- PROP_0,
- PROP_DISPLAY,
-#ifdef GST_WLSINK_ENHANCEMENT
- PROP_ROTATE_ANGLE,
- PROP_DISPLAY_GEOMETRY_METHOD,
- PROP_ORIENTATION,
- PROP_FLIP
-#endif
-};
-
-GST_DEBUG_CATEGORY (gsttizenwl_debug);
-#define GST_CAT_DEFAULT gsttizenwl_debug
-
-static GstStaticPadTemplate sink_template = GST_STATIC_PAD_TEMPLATE ("sink",
- GST_PAD_SINK,
- GST_PAD_ALWAYS,
- GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE
- ("{ BGRx, BGRA, RGBx, xBGR, xRGB, RGBA, ABGR, ARGB, RGB, BGR, "
- "RGB16, BGR16, YUY2, YVYU, UYVY, AYUV, NV12, NV21, NV16, "
-#ifdef GST_WLSINK_ENHANCEMENT
- "SN12, ST12, "
-#endif
- "YUV9, YVU9, Y41B, I420, YV12, Y42B, v308 }"))
- );
-
-static void gst_wayland_sink_get_property (GObject * object,
- guint prop_id, GValue * value, GParamSpec * pspec);
-static void gst_wayland_sink_set_property (GObject * object,
- guint prop_id, const GValue * value, GParamSpec * pspec);
-static void gst_wayland_sink_finalize (GObject * object);
-
-static GstStateChangeReturn gst_wayland_sink_change_state (GstElement * element,
- GstStateChange transition);
-static void gst_wayland_sink_set_context (GstElement * element,
- GstContext * context);
-
-static GstCaps *gst_wayland_sink_get_caps (GstBaseSink * bsink,
- GstCaps * filter);
-static gboolean gst_wayland_sink_set_caps (GstBaseSink * bsink, GstCaps * caps);
-static gboolean gst_wayland_sink_preroll (GstBaseSink * bsink,
- GstBuffer * buffer);
-static gboolean
-gst_wayland_sink_propose_allocation (GstBaseSink * bsink, GstQuery * query);
-static gboolean gst_wayland_sink_render (GstBaseSink * bsink,
- GstBuffer * buffer);
-
-/* VideoOverlay interface */
-static void gst_wayland_sink_videooverlay_init (GstVideoOverlayInterface *
- iface);
-static void gst_wayland_sink_set_window_handle (GstVideoOverlay * overlay,
- guintptr handle);
-static void gst_wayland_sink_set_render_rectangle (GstVideoOverlay * overlay,
- gint x, gint y, gint w, gint h);
-static void gst_wayland_sink_expose (GstVideoOverlay * overlay);
-
-/* WaylandVideo interface */
-static void gst_wayland_sink_waylandvideo_init (GstWaylandVideoInterface *
- iface);
-static void gst_wayland_sink_begin_geometry_change (GstWaylandVideo * video);
-static void gst_wayland_sink_end_geometry_change (GstWaylandVideo * video);
-#ifdef GST_WLSINK_ENHANCEMENT
-static void gst_wayland_sink_update_window_geometry (GstTizenwlSink * sink);
-static void render_last_buffer (GstTizenwlSink * sink);
-static void gst_wayland_sink_render_last_buffer (GstTizenwlSink * sink);
-
-#endif
-
-#define gst_wayland_sink_parent_class parent_class
-G_DEFINE_TYPE_WITH_CODE (GstTizenwlSink, gst_wayland_sink, GST_TYPE_VIDEO_SINK,
- G_IMPLEMENT_INTERFACE (GST_TYPE_VIDEO_OVERLAY,
- gst_wayland_sink_videooverlay_init)
- G_IMPLEMENT_INTERFACE (GST_TYPE_WAYLAND_VIDEO,
- gst_wayland_sink_waylandvideo_init));
-
-static void
-gst_wayland_sink_class_init (GstTizenwlSinkClass * klass)
-{
- FUNCTION_ENTER ();
- GObjectClass *gobject_class;
- GstElementClass *gstelement_class;
- GstBaseSinkClass *gstbasesink_class;
-
- gobject_class = (GObjectClass *) klass;
- gstelement_class = (GstElementClass *) klass;
- gstbasesink_class = (GstBaseSinkClass *) klass;
-
- gobject_class->set_property = gst_wayland_sink_set_property;
- gobject_class->get_property = gst_wayland_sink_get_property;
- gobject_class->finalize = GST_DEBUG_FUNCPTR (gst_wayland_sink_finalize);
-
- gst_element_class_add_pad_template (gstelement_class,
- gst_static_pad_template_get (&sink_template));
-
- gst_element_class_set_static_metadata (gstelement_class,
- "wayland video sink", "Sink/Video",
- "Output to wayland surface",
- "Sreerenj Balachandran <sreerenj.balachandran@intel.com>, "
- "George Kiagiadakis <george.kiagiadakis@collabora.com>");
-
- gstelement_class->change_state =
- GST_DEBUG_FUNCPTR (gst_wayland_sink_change_state);
- gstelement_class->set_context =
- GST_DEBUG_FUNCPTR (gst_wayland_sink_set_context);
-
- gstbasesink_class->get_caps = GST_DEBUG_FUNCPTR (gst_wayland_sink_get_caps);
- gstbasesink_class->set_caps = GST_DEBUG_FUNCPTR (gst_wayland_sink_set_caps);
- gstbasesink_class->preroll = GST_DEBUG_FUNCPTR (gst_wayland_sink_preroll);
- gstbasesink_class->propose_allocation =
- GST_DEBUG_FUNCPTR (gst_wayland_sink_propose_allocation);
- gstbasesink_class->render = GST_DEBUG_FUNCPTR (gst_wayland_sink_render);
-
- g_object_class_install_property (gobject_class, PROP_DISPLAY,
- g_param_spec_string ("display", "Wayland Display name", "Wayland "
- "display name to connect to, if not supplied via the GstContext",
- NULL, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
-#ifdef GST_WLSINK_ENHANCEMENT
- g_object_class_install_property (gobject_class, PROP_ROTATE_ANGLE,
- g_param_spec_enum ("rotate", "Rotate angle",
- "Rotate angle of display output",
- GST_TYPE_WAYLANDSINK_ROTATE_ANGLE, DEGREE_0,
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
-
- 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_WAYLANDSINK_DISPLAY_GEOMETRY_METHOD,
- DEF_DISPLAY_GEOMETRY_METHOD,
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
-
- 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_WAYLANDSINK_ROTATE_ANGLE, DEGREE_0,
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
-
- g_object_class_install_property (gobject_class, PROP_FLIP,
- g_param_spec_enum ("flip", "Display flip",
- "Flip for display",
- GST_TYPE_WAYLANDSINK_FLIP, DEF_DISPLAY_FLIP,
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
-
-#endif
-}
-
-static void
-gst_wayland_sink_init (GstTizenwlSink * sink)
-{
- FUNCTION_ENTER ();
-
- sink->display_geometry_method = DEF_DISPLAY_GEOMETRY_METHOD;
- sink->flip = DEF_DISPLAY_FLIP;
- sink->rotate_angle = DEGREE_0;
- sink->orientation = DEGREE_0;
-
- g_mutex_init (&sink->display_lock);
- g_mutex_init (&sink->render_lock);
-}
-
-static void
-gst_wayland_sink_get_property (GObject * object,
- guint prop_id, GValue * value, GParamSpec * pspec)
-{
- FUNCTION_ENTER ();
-
- GstTizenwlSink *sink = GST_WAYLAND_SINK (object);
- switch (prop_id) {
- case PROP_DISPLAY:
- GST_OBJECT_LOCK (sink);
- g_value_set_string (value, sink->display_name);
- GST_OBJECT_UNLOCK (sink);
- break;
-#ifdef GST_WLSINK_ENHANCEMENT
- case PROP_ROTATE_ANGLE:
- g_value_set_enum (value, sink->rotate_angle);
- break;
- case PROP_DISPLAY_GEOMETRY_METHOD:
- g_value_set_enum (value, sink->display_geometry_method);
- break;
- case PROP_ORIENTATION:
- g_value_set_enum (value, sink->orientation);
- break;
- case PROP_FLIP:
- g_value_set_enum (value, sink->flip);
- break;
-#endif
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static void
-gst_wayland_sink_set_property (GObject * object,
- guint prop_id, const GValue * value, GParamSpec * pspec)
-{
- FUNCTION_ENTER ();
-
- GstTizenwlSink *sink = GST_WAYLAND_SINK (object);
- switch (prop_id) {
- case PROP_DISPLAY:
- GST_OBJECT_LOCK (sink);
- sink->display_name = g_value_dup_string (value);
- GST_OBJECT_UNLOCK (sink);
- break;
-#ifdef GST_WLSINK_ENHANCEMENT
- case PROP_ROTATE_ANGLE:
- sink->rotate_angle = g_value_get_enum (value);
- GST_INFO_OBJECT (sink, "Rotate angle is set (%d)", sink->rotate_angle);
- if (sink->window) {
- gst_wl_window_set_rotate_angle (sink->window, sink->rotate_angle);
- }
- sink->video_info_changed = TRUE;
- if (GST_STATE (sink) == GST_STATE_PAUSED) {
- /*need to render last buffer */
- gst_wayland_sink_render_last_buffer (sink);
- }
- break;
- case PROP_DISPLAY_GEOMETRY_METHOD:
- sink->display_geometry_method = g_value_get_enum (value);
- GST_INFO_OBJECT (sink, "Display geometry method is set (%d)",
- sink->display_geometry_method);
- if (sink->window) {
- gst_wl_window_set_disp_geo_method (sink->window,
- sink->display_geometry_method);
- }
- sink->video_info_changed = TRUE;
- if (GST_STATE (sink) == GST_STATE_PAUSED) {
- /*need to render last buffer */
- gst_wayland_sink_render_last_buffer (sink);
- }
- break;
- case PROP_ORIENTATION:
- sink->orientation = g_value_get_enum (value);
- GST_INFO_OBJECT (sink, "Orientation is set (%d)", sink->orientation);
- if (sink->window) {
- gst_wl_window_set_orientation (sink->window, sink->orientation);
- }
- sink->video_info_changed = TRUE;
- if (GST_STATE (sink) == GST_STATE_PAUSED) {
- /*need to render last buffer */
- gst_wayland_sink_render_last_buffer (sink);
- }
- break;
- case PROP_FLIP:
- sink->flip = g_value_get_enum (value);
- GST_INFO_OBJECT (sink, "flip is set (%d)", sink->flip);
- if (sink->flip) {
- gst_wl_window_set_flip (sink->window, sink->flip);
- }
- sink->video_info_changed = TRUE;
- if (GST_STATE (sink) == GST_STATE_PAUSED) {
- /*need to render last buffer */
- gst_wayland_sink_render_last_buffer (sink);
- }
- break;
-#endif
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static void
-gst_wayland_sink_finalize (GObject * object)
-{
- FUNCTION_ENTER ();
-
- GstTizenwlSink *sink = GST_WAYLAND_SINK (object);
- GST_DEBUG_OBJECT (sink, "Finalizing the sink..");
-
- if (sink->last_buffer)
- gst_buffer_unref (sink->last_buffer);
- if (sink->display) {
- /* see comment about this call in gst_wayland_sink_change_state() */
-#ifdef GST_WLSINK_ENHANCEMENT
- if (sink->pool && !sink->display->is_native_format)
-#else
- if (sink->pool)
-#endif
- gst_wayland_compositor_release_all_buffers (GST_WAYLAND_BUFFER_POOL
- (sink->pool));
-
- g_object_unref (sink->display);
- sink->display = NULL;
- }
- if (sink->window) {
- g_object_unref (sink->window);
- sink->window = NULL;
- }
- if (sink->pool) {
- gst_object_unref (sink->pool);
- sink->pool = NULL;
- }
-
- if (sink->display_name) {
- g_free (sink->display_name);
- sink->display_name = NULL;
- }
-
- g_mutex_clear (&sink->display_lock);
- g_mutex_clear (&sink->render_lock);
-
- G_OBJECT_CLASS (parent_class)->finalize (object);
-}
-
-/* must be called with the display_lock */
-static void
-gst_wayland_sink_set_display_from_context (GstTizenwlSink * sink,
- GstContext * context)
-{
- FUNCTION_ENTER ();
-
- struct wl_display *display;
- GError *error = NULL;
-
- display = gst_wayland_display_handle_context_get_handle (context);
- sink->display = gst_wl_display_new_existing (display, FALSE, &error);
-
- if (error) {
- GST_ELEMENT_WARNING (sink, RESOURCE, OPEN_READ_WRITE,
- ("Could not set display handle"),
- ("Failed to use the external wayland display: '%s'", error->message));
- g_error_free (error);
- }
-}
-
-static gboolean
-gst_wayland_sink_find_display (GstTizenwlSink * sink)
-{
- FUNCTION_ENTER ();
-
- GstQuery *query;
- GstMessage *msg;
- GstContext *context = NULL;
- GError *error = NULL;
- gboolean ret = TRUE;
-
- g_mutex_lock (&sink->display_lock);
-
- if (!sink->display) {
- /* first query upstream for the needed display handle */
- query = gst_query_new_context (GST_WAYLAND_DISPLAY_HANDLE_CONTEXT_TYPE);
- if (gst_pad_peer_query (GST_VIDEO_SINK_PAD (sink), query)) {
- gst_query_parse_context (query, &context);
- gst_wayland_sink_set_display_from_context (sink, context);
- }
- gst_query_unref (query);
-
- if (G_LIKELY (!sink->display)) {
- /* now ask the application to set the display handle */
- msg = gst_message_new_need_context (GST_OBJECT_CAST (sink),
- GST_WAYLAND_DISPLAY_HANDLE_CONTEXT_TYPE);
-
- g_mutex_unlock (&sink->display_lock);
- gst_element_post_message (GST_ELEMENT_CAST (sink), msg);
- /* at this point we expect gst_wayland_sink_set_context
- * to get called and fill sink->display */
- g_mutex_lock (&sink->display_lock);
-
- if (!sink->display) {
- /* if the application didn't set a display, let's create it ourselves */
- GST_OBJECT_LOCK (sink);
- sink->display = gst_wl_display_new (sink->display_name, &error);
- GST_OBJECT_UNLOCK (sink);
-
- if (error) {
- GST_ELEMENT_WARNING (sink, RESOURCE, OPEN_READ_WRITE,
- ("Could not initialise Wayland output"),
- ("Failed to create GstWlDisplay: '%s'", error->message));
- g_error_free (error);
- ret = FALSE;
- } else {
- /* inform the world about the new display */
- context =
- gst_wayland_display_handle_context_new (sink->display->display);
- msg = gst_message_new_have_context (GST_OBJECT_CAST (sink), context);
- gst_element_post_message (GST_ELEMENT_CAST (sink), msg);
- }
- }
- }
- }
-
- g_mutex_unlock (&sink->display_lock);
-
- return ret;
-}
-
-static GstStateChangeReturn
-gst_wayland_sink_change_state (GstElement * element, GstStateChange transition)
-{
- FUNCTION_ENTER ();
-
- GstTizenwlSink *sink = GST_WAYLAND_SINK (element);
- GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
-
- switch (transition) {
- case GST_STATE_CHANGE_NULL_TO_READY:
- if (!gst_wayland_sink_find_display (sink))
- return GST_STATE_CHANGE_FAILURE;
- break;
- default:
- break;
- }
-
- ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
- if (ret == GST_STATE_CHANGE_FAILURE)
- return ret;
-
- switch (transition) {
- case GST_STATE_CHANGE_PAUSED_TO_READY:
- gst_buffer_replace (&sink->last_buffer, NULL);
- if (sink->window) {
- if (gst_wl_window_is_toplevel (sink->window)) {
- g_clear_object (&sink->window);
- } else {
- /* remove buffer from surface, show nothing */
- wl_surface_attach (sink->window->surface, NULL, 0, 0);
- wl_surface_damage (sink->window->surface, 0, 0,
- sink->window->surface_width, sink->window->surface_height);
- wl_surface_commit (sink->window->surface);
- wl_display_flush (sink->display->display);
- }
- }
- break;
- case GST_STATE_CHANGE_READY_TO_NULL:
- g_mutex_lock (&sink->display_lock);
- /* If we had a toplevel window, we most likely have our own connection
- * to the display too, and it is a good idea to disconnect and allow
- * potentially the application to embed us with GstVideoOverlay
- * (which requires to re-use the same display connection as the parent
- * surface). If we didn't have a toplevel window, then the display
- * connection that we have is definitely shared with the application
- * and it's better to keep it around (together with the window handle)
- * to avoid requesting them again from the application if/when we are
- * restarted (GstVideoOverlay behaves like that in other sinks)
- */
- if (sink->display && !sink->window) { /* -> the window was toplevel */
- /* Force all buffers to return to the pool, regardless of
- * whether the compositor has released them or not. We are
- * going to kill the display, so we need to return all buffers
- * to be destroyed before this happens.
- * Note that this is done here instead of the pool destructor
- * because the buffers hold a reference to the pool. Also,
- * the buffers can only be unref'ed from the display's event loop
- * and the pool holds a reference to the display. If we drop
- * our references here, when the compositor releases the buffers,
- * they will be unref'ed from the event loop thread, which will
- * unref the pool and therefore the display, which will try to
- * stop the thread from within itself and cause a deadlock.
- */
- if (sink->pool) {
- gst_wayland_compositor_release_all_buffers (GST_WAYLAND_BUFFER_POOL
- (sink->pool));
- }
- g_clear_object (&sink->display);
- g_clear_object (&sink->pool);
- }
- g_mutex_unlock (&sink->display_lock);
- break;
- default:
- break;
- }
-
- return ret;
-}
-
-static void
-gst_wayland_sink_set_context (GstElement * element, GstContext * context)
-{
- FUNCTION_ENTER ();
-
- GstTizenwlSink *sink = GST_WAYLAND_SINK (element);
- if (gst_context_has_context_type (context,
- GST_WAYLAND_DISPLAY_HANDLE_CONTEXT_TYPE)) {
- g_mutex_lock (&sink->display_lock);
- if (G_LIKELY (!sink->display)) {
- gst_wayland_sink_set_display_from_context (sink, context);
- } else {
- GST_WARNING_OBJECT (element, "changing display handle is not supported");
- g_mutex_unlock (&sink->display_lock);
- return;
- }
- g_mutex_unlock (&sink->display_lock);
- }
-
- GST_INFO ("element %p context %p", element, context);
- if (GST_ELEMENT_CLASS (parent_class)->set_context)
- GST_ELEMENT_CLASS (parent_class)->set_context (element, context);
-}
-
-static GstCaps *
-gst_wayland_sink_get_caps (GstBaseSink * bsink, GstCaps * filter)
-{
- FUNCTION_ENTER ();
-
- GstTizenwlSink *sink;
- GstCaps *caps;
- sink = GST_WAYLAND_SINK (bsink);
-
- caps = gst_pad_get_pad_template_caps (GST_VIDEO_SINK_PAD (sink));
-
- g_mutex_lock (&sink->display_lock);
-
- if (sink->display) {
- GValue list = G_VALUE_INIT;
- GValue value = G_VALUE_INIT;
- GArray *formats;
- gint i;
-#ifdef GST_WLSINK_ENHANCEMENT
- uint32_t fmt;
-#else
- enum wl_shm_format fmt;
-#endif
-
- g_value_init (&list, GST_TYPE_LIST);
- g_value_init (&value, G_TYPE_STRING);
-
- formats = sink->display->formats;
- for (i = 0; i < formats->len; i++) {
- fmt = g_array_index (formats, uint32_t, i);
- g_value_set_string (&value, gst_wayland_format_to_string (fmt));
- gst_value_list_append_value (&list, &value);
-#ifdef GST_WLSINK_ENHANCEMENT
- /* TBM doesn't support SN12. So we add SN12 manually as supported format.
- * SN12 is exactly same with NV12.
- */
- if (fmt == TBM_FORMAT_NV12) {
- g_value_set_string (&value,
- gst_video_format_to_string (GST_VIDEO_FORMAT_SN12));
- gst_value_list_append_value (&list, &value);
- }
-#endif
- }
-
- caps = gst_caps_make_writable (caps);
- gst_structure_set_value (gst_caps_get_structure (caps, 0), "format", &list);
-
- GST_DEBUG_OBJECT (sink, "display caps: %" GST_PTR_FORMAT, caps);
- }
-
- g_mutex_unlock (&sink->display_lock);
-
- if (filter) {
- GstCaps *intersection;
-
- intersection =
- gst_caps_intersect_full (filter, caps, GST_CAPS_INTERSECT_FIRST);
- gst_caps_unref (caps);
- caps = intersection;
- }
-
- return caps;
-}
-
-static gboolean
-gst_wayland_sink_set_caps (GstBaseSink * bsink, GstCaps * caps)
-{
- FUNCTION_ENTER ();
-
- GstTizenwlSink *sink;
- GstBufferPool *newpool;
- GstVideoInfo info;
-#ifdef GST_WLSINK_ENHANCEMENT
- uint32_t format;
-#else
- enum wl_shm_format format;
-#endif
- GArray *formats;
- gint i;
- GstStructure *structure;
- static GstAllocationParams params = { 0, 0, 0, 15, };
- sink = GST_WAYLAND_SINK (bsink);
-
- GST_DEBUG_OBJECT (sink, "set caps %" GST_PTR_FORMAT, caps);
-
- /* extract info from caps */
- if (!gst_video_info_from_caps (&info, caps))
- goto invalid_format;
-#ifdef GST_WLSINK_ENHANCEMENT
- sink->caps = gst_caps_copy (caps);
-#endif
-
- format = gst_video_format_to_wayland_format (GST_VIDEO_INFO_FORMAT (&info));
- if ((gint) format == -1)
- goto invalid_format;
-
- /* verify we support the requested format */
- formats = sink->display->formats;
- for (i = 0; i < formats->len; i++) {
- if (g_array_index (formats, uint32_t, i) == format)
- break;
- }
-
- if (i >= formats->len)
- goto unsupported_format;
-
-#ifdef GST_WLSINK_ENHANCEMENT
- if (GST_VIDEO_INFO_FORMAT (&info) == GST_VIDEO_FORMAT_SN12 ||
- GST_VIDEO_INFO_FORMAT (&info) == GST_VIDEO_FORMAT_ST12) {
- sink->display->is_native_format = TRUE;
- } else {
- sink->display->is_native_format = FALSE;
-
- /* create a new pool for the new configuration */
- newpool = gst_wayland_buffer_pool_new (sink->display);
- if (!newpool)
- goto pool_failed;
-
- structure = gst_buffer_pool_get_config (newpool);
- gst_buffer_pool_config_set_params (structure, caps, info.size, 2, 0);
- gst_buffer_pool_config_set_allocator (structure, NULL, ¶ms);
- if (!gst_buffer_pool_set_config (newpool, structure))
- goto config_failed;
-
- gst_object_replace ((GstObject **) & sink->pool, (GstObject *) newpool);
- gst_object_unref (newpool);
-
- }
- /* store the video info */
- sink->video_info = info;
- sink->video_info_changed = TRUE;
-#else
- /* create a new pool for the new configuration */
- newpool = gst_wayland_buffer_pool_new (sink->display);
- if (!newpool)
- goto pool_failed;
-
- structure = gst_buffer_pool_get_config (newpool);
- gst_buffer_pool_config_set_params (structure, caps, info.size, 2, 0);
- gst_buffer_pool_config_set_allocator (structure, NULL, ¶ms);
- if (!gst_buffer_pool_set_config (newpool, structure))
- goto config_failed;
-
- /* store the video info */
- sink->video_info = info;
- sink->video_info_changed = TRUE;
-
- gst_object_replace ((GstObject **) & sink->pool, (GstObject *) newpool);
- gst_object_unref (newpool);
-#endif
- return TRUE;
-
-invalid_format:
- {
- GST_DEBUG_OBJECT (sink,
- "Could not locate image format from caps %" GST_PTR_FORMAT, caps);
- return FALSE;
- }
-unsupported_format:
- {
- GST_DEBUG_OBJECT (sink, "Format %s is not available on the display",
- gst_wayland_format_to_string (format));
- return FALSE;
- }
-pool_failed:
- {
- GST_DEBUG_OBJECT (sink, "Failed to create new pool");
- return FALSE;
- }
-config_failed:
- {
- GST_DEBUG_OBJECT (bsink, "failed setting config");
- gst_object_unref (newpool);
- return FALSE;
- }
-}
-
-static gboolean
-gst_wayland_sink_propose_allocation (GstBaseSink * bsink, GstQuery * query)
-{
- FUNCTION_ENTER ();
-
- GstTizenwlSink *sink = GST_WAYLAND_SINK (bsink);
- GstBufferPool *pool = NULL;
- GstStructure *config;
- GstCaps *caps;
- guint size;
- gboolean need_pool;
-
- if (sink->display->is_native_format == TRUE)
- return TRUE;
-
- gst_query_parse_allocation (query, &caps, &need_pool);
-
- if (caps == NULL)
- goto no_caps;
-
- if (sink->pool)
- pool = gst_object_ref (sink->pool);
-
- if (pool != NULL) {
- GstCaps *pcaps;
-
- /* we had a pool, check caps */
- config = gst_buffer_pool_get_config (pool);
- gst_buffer_pool_config_get_params (config, &pcaps, &size, NULL, NULL);
-
- if (!gst_caps_is_equal (caps, pcaps)) {
- /* different caps, we can't use this pool */
- gst_object_unref (pool);
- pool = NULL;
- }
- gst_structure_free (config);
- }
-
- if (pool == NULL && need_pool) {
- GstVideoInfo info;
-
- if (!gst_video_info_from_caps (&info, caps))
- goto invalid_caps;
-
- GST_DEBUG_OBJECT (sink, "create new pool");
- pool = gst_wayland_buffer_pool_new (sink->display);
-
- /* the normal size of a frame */
- size = info.size;
-
- config = gst_buffer_pool_get_config (pool);
- gst_buffer_pool_config_set_params (config, caps, size, 2, 0);
- if (!gst_buffer_pool_set_config (pool, config))
- goto config_failed;
- }
- if (pool) {
- gst_query_add_allocation_pool (query, pool, size, 2, 0);
- gst_object_unref (pool);
- }
-
- return TRUE;
-
- /* ERRORS */
-no_caps:
- {
- GST_DEBUG_OBJECT (bsink, "no caps specified");
- return FALSE;
- }
-invalid_caps:
- {
- GST_DEBUG_OBJECT (bsink, "invalid caps specified");
- return FALSE;
- }
-config_failed:
- {
- GST_DEBUG_OBJECT (bsink, "failed setting config");
- gst_object_unref (pool);
- return FALSE;
- }
-}
-
-static GstFlowReturn
-gst_wayland_sink_preroll (GstBaseSink * bsink, GstBuffer * buffer)
-{
- FUNCTION_ENTER ();
-
- GST_DEBUG_OBJECT (bsink, "preroll buffer %p", buffer);
- return gst_wayland_sink_render (bsink, buffer);
-}
-
-static void
-frame_redraw_callback (void *data, struct wl_callback *callback, uint32_t time)
-{
- FUNCTION_ENTER ();
-
- GstTizenwlSink *sink = data;
-
- GST_LOG ("frame_redraw_cb");
-
- g_atomic_int_set (&sink->redraw_pending, FALSE);
- wl_callback_destroy (callback);
-}
-
-static const struct wl_callback_listener frame_callback_listener = {
- frame_redraw_callback
-};
-
-/* must be called with the render lock */
-static void
-render_last_buffer (GstTizenwlSink * sink)
-{
- FUNCTION_ENTER ();
-
- GstWlMeta *meta;
- struct wl_surface *surface;
- struct wl_callback *callback;
-
- meta = gst_buffer_get_wl_meta (sink->last_buffer);
- surface = gst_wl_window_get_wl_surface (sink->window);
-
- g_atomic_int_set (&sink->redraw_pending, TRUE);
- callback = wl_surface_frame (surface);
- wl_callback_add_listener (callback, &frame_callback_listener, sink);
-
- /* Here we essentially add a reference to the buffer. This represents
- * the fact that the compositor is using the buffer and it should
- * not return back to the pool and be reused until the compositor
- * releases it. The release is handled internally in the pool */
- gst_wayland_compositor_acquire_buffer (meta->pool, sink->last_buffer);
-
- GST_DEBUG ("wl_surface_attach wl_buffer %p", meta->wbuffer);
-
- wl_surface_attach (surface, meta->wbuffer, 0, 0);
- wl_surface_damage (surface, 0, 0, sink->window->surface_width,
- sink->window->surface_height);
-
- wl_surface_commit (surface);
- wl_display_flush (sink->display->display);
-}
-
-static GstFlowReturn
-gst_wayland_sink_render (GstBaseSink * bsink, GstBuffer * buffer)
-{
- FUNCTION_ENTER ();
-
- GstTizenwlSink *sink = GST_WAYLAND_SINK (bsink);
- GstBuffer *to_render;
- GstWlMeta *meta;
- GstFlowReturn ret = GST_FLOW_OK;
-
-#ifdef GST_WLSINK_ENHANCEMENT
- GstBufferPool *newpool;
- GstStructure *structure;
- static GstAllocationParams params = { 0, 0, 0, 15, };
-#endif
-
- g_mutex_lock (&sink->render_lock);
-
- GST_LOG_OBJECT (sink, "render buffer %p", buffer);
-
- if (G_UNLIKELY (!sink->window)) {
- /* ask for window handle. Unlock render_lock while doing that because
- * set_window_handle & friends will lock it in this context */
- g_mutex_unlock (&sink->render_lock);
- gst_video_overlay_prepare_window_handle (GST_VIDEO_OVERLAY (sink));
- g_mutex_lock (&sink->render_lock);
-
- if (sink->window) {
- /* inform the window about our caps */
- gst_wl_window_set_video_info (sink->window, &sink->video_info);
- } else {
- /* if we were not provided a window, create one ourselves */
- sink->window =
- gst_wl_window_new_toplevel (sink->display, &sink->video_info);
- }
-#ifdef GST_WLSINK_ENHANCEMENT
- gst_wayland_sink_update_window_geometry (sink);
- sink->video_info_changed = TRUE;
-#else
- sink->video_info_changed = FALSE;
-#endif
- }
-
- /* drop buffers until we get a frame callback */
- if (g_atomic_int_get (&sink->redraw_pending) == TRUE)
- goto done;
-
- if (G_UNLIKELY (sink->video_info_changed)) {
- gst_wl_window_set_video_info (sink->window, &sink->video_info);
- sink->video_info_changed = FALSE;
- }
- GST_INFO ("window->render_rectangle(%d,%d %d x %d)",
- sink->window->render_rectangle.x,
- sink->window->render_rectangle.y,
- sink->window->render_rectangle.w, sink->window->render_rectangle.h);
- GST_INFO ("window->surface_width(%d),window->surface_height(%d)",
- sink->window->surface_width, sink->window->surface_height);
-
- /* now that we have for sure set the video info on the window, it must have
- * a valid size, otherwise this means that the application has called
- * set_window_handle() without calling set_render_rectangle(), which is
- * absolutely necessary for us.
- */
- if (G_UNLIKELY (sink->window->surface_width == 0 ||
- sink->window->surface_height == 0))
- goto no_window_size;
-
- meta = gst_buffer_get_wl_meta (buffer);
-
- if (meta && meta->pool->display == sink->display) {
- GST_LOG_OBJECT (sink, "buffer %p from our pool, writing directly", buffer);
- to_render = buffer;
- } else {
- GstMapInfo src;
- GST_LOG_OBJECT (sink, "buffer %p not from our pool, copying", buffer);
-
-#ifdef GST_WLSINK_ENHANCEMENT
- if (sink->display->is_native_format == TRUE) {
- /*in case of SN12 or ST12 video format */
- GstMemory *mem;
- GstMapInfo mem_info = GST_MAP_INFO_INIT;
- MMVideoBuffer *mm_video_buf = NULL;
- int i = 0;
-
- mem = gst_buffer_peek_memory (buffer, 1);
- gst_memory_map (mem, &mem_info, GST_MAP_READ);
- mm_video_buf = (MMVideoBuffer *) mem_info.data;
- gst_memory_unmap (mem, &mem_info);
-
- if (mm_video_buf == NULL) {
- GST_WARNING_OBJECT (sink, "mm_video_buf is NULL. Skip rendering");
- return ret;
- }
- /* assign mm_video_buf info */
- if (mm_video_buf->type == MM_VIDEO_BUFFER_TYPE_TBM_BO) {
- GST_DEBUG_OBJECT (sink, "TBM bo %p %p %p", mm_video_buf->handle.bo[0],
- mm_video_buf->handle.bo[1], mm_video_buf->handle.bo[2]);
-
- sink->display->native_video_size = 0;
-
- for (i = 0; i < NV_BUF_PLANE_NUM; i++) {
- if (mm_video_buf->handle.bo[i] != NULL) {
- sink->display->bo[i] = mm_video_buf->handle.bo[i];
- } else {
- sink->display->bo[i] = 0;
- }
- sink->display->plane_size[i] = mm_video_buf->size[i];
- sink->display->stride_width[i] = mm_video_buf->stride_width[i];
- sink->display->stride_height[i] = mm_video_buf->stride_height[i];
- sink->display->native_video_size += sink->display->plane_size[i];
- }
- } else {
- GST_ERROR_OBJECT (sink, "Buffer type is not TBM");
- return ret;
- }
-
- if (!sink->pool) {
-
- /* create a new pool for the new configuration */
- newpool = gst_wayland_buffer_pool_new (sink->display);
- if (!newpool) {
- GST_DEBUG_OBJECT (sink, "Failed to create new pool");
- return FALSE;
- }
- structure = gst_buffer_pool_get_config (newpool);
- /*When the buffer is released, Core compare size with buffer size,
- wl_buffer is not created if the size is same. It is a very critical problem
- So we set 0 to size */
- gst_buffer_pool_config_set_params (structure, sink->caps, 0, 2, 0);
- gst_buffer_pool_config_set_allocator (structure, NULL, ¶ms);
- if (!gst_buffer_pool_set_config (newpool, structure)) {
- GST_DEBUG_OBJECT (bsink, "failed setting config");
- gst_object_unref (newpool);
- return FALSE;
- }
-
- gst_object_replace ((GstObject **) & sink->pool, (GstObject *) newpool);
- gst_object_unref (newpool);
-
- }
-
- if (!gst_buffer_pool_set_active (sink->pool, TRUE))
- goto activate_failed;
-
- ret = gst_buffer_pool_acquire_buffer (sink->pool, &to_render, NULL);
- if (ret != GST_FLOW_OK)
- goto no_buffer;
-
-
- /*add displaying buffer */
- GstWlMeta *meta;
- meta = gst_buffer_get_wl_meta (to_render);
- gst_wayland_buffer_pool_add_displaying_buffer (sink->pool, meta, buffer);
-
- } else {
- /*in case of normal video format and pool is not our pool */
-
- if (!sink->pool)
- goto no_pool;
-
- if (!gst_buffer_pool_set_active (sink->pool, TRUE))
- goto activate_failed;
-
- ret = gst_buffer_pool_acquire_buffer (sink->pool, &to_render, NULL);
- if (ret != GST_FLOW_OK)
- goto no_buffer;
-
- gst_buffer_map (buffer, &src, GST_MAP_READ);
- gst_buffer_fill (to_render, 0, src.data, src.size);
- gst_buffer_unmap (buffer, &src);
- }
-#else
- if (!sink->pool)
- goto no_pool;
-
- if (!gst_buffer_pool_set_active (sink->pool, TRUE))
- goto activate_failed;
-
- ret = gst_buffer_pool_acquire_buffer (sink->pool, &to_render, NULL);
- if (ret != GST_FLOW_OK)
- goto no_buffer;
-
- gst_buffer_map (buffer, &src, GST_MAP_READ);
- gst_buffer_fill (to_render, 0, src.data, src.size);
- gst_buffer_unmap (buffer, &src);
-#endif
- }
-
- gst_buffer_replace (&sink->last_buffer, to_render);
- render_last_buffer (sink);
-
- if (buffer != to_render) {
- GST_LOG_OBJECT (sink, "Decrease ref count of buffer");
- gst_buffer_unref (to_render);
- }
- goto done;
-
-no_window_size:
- {
- GST_ELEMENT_ERROR (sink, RESOURCE, WRITE,
- ("Window has no size set"),
- ("Make sure you set the size after calling set_window_handle"));
- ret = GST_FLOW_ERROR;
- goto done;
- }
-no_buffer:
- {
- GST_WARNING_OBJECT (sink, "could not create image");
- goto done;
- }
-no_pool:
- {
- GST_ELEMENT_ERROR (sink, RESOURCE, WRITE,
- ("Internal error: can't allocate images"),
- ("We don't have a bufferpool negotiated"));
- ret = GST_FLOW_ERROR;
- goto done;
- }
-activate_failed:
- {
- GST_ERROR_OBJECT (sink, "failed to activate bufferpool.");
- ret = GST_FLOW_ERROR;
- goto done;
- }
-done:
- {
- g_mutex_unlock (&sink->render_lock);
- return ret;
- }
-}
-
-static void
-gst_wayland_sink_videooverlay_init (GstVideoOverlayInterface * iface)
-{
- FUNCTION_ENTER ();
-
- iface->set_window_handle = gst_wayland_sink_set_window_handle;
- iface->set_render_rectangle = gst_wayland_sink_set_render_rectangle;
- iface->expose = gst_wayland_sink_expose;
-}
-
-static void
-gst_wayland_sink_set_window_handle (GstVideoOverlay * overlay, guintptr handle)
-{
- FUNCTION_ENTER ();
-
- GstTizenwlSink *sink = GST_WAYLAND_SINK (overlay);
- struct wl_surface *surface = (struct wl_surface *) handle;
-
- g_return_if_fail (sink != NULL);
-
- if (sink->window != NULL) {
- GST_WARNING_OBJECT (sink, "changing window handle is not supported");
- return;
- }
-
- g_mutex_lock (&sink->render_lock);
-
- GST_DEBUG_OBJECT (sink, "Setting window handle %" GST_PTR_FORMAT,
- (void *) handle);
-
- g_clear_object (&sink->window);
-
- if (handle) {
- if (G_LIKELY (gst_wayland_sink_find_display (sink))) {
- /* we cannot use our own display with an external window handle */
- if (G_UNLIKELY (sink->display->own_display)) {
- GST_ELEMENT_ERROR (sink, RESOURCE, OPEN_READ_WRITE,
- ("Application did not provide a wayland display handle"),
- ("waylandsink cannot use an externally-supplied surface without "
- "an externally-supplied display handle. Consider providing a "
- "display handle from your application with GstContext"));
- } else {
- sink->window = gst_wl_window_new_in_surface (sink->display, surface);
- GST_DEBUG ("sink->window %p", sink->window);
- }
- } else {
- GST_ERROR_OBJECT (sink, "Failed to find display handle, "
- "ignoring window handle");
- }
- }
-#ifdef GST_WLSINK_ENHANCEMENT
- gst_wayland_sink_update_window_geometry (sink);
-#endif
-
- g_mutex_unlock (&sink->render_lock);
-}
-
-#ifdef GST_WLSINK_ENHANCEMENT
-static void
-gst_wayland_sink_update_window_geometry (GstTizenwlSink * sink)
-{
- FUNCTION_ENTER ();
- g_return_if_fail (sink != NULL);
- g_return_if_fail (sink->window != NULL);
-
- gst_wl_window_set_rotate_angle (sink->window, sink->rotate_angle);
- gst_wl_window_set_disp_geo_method (sink->window,
- sink->display_geometry_method);
- gst_wl_window_set_orientation (sink->window, sink->orientation);
- gst_wl_window_set_flip (sink->window, sink->flip);
-}
-
-static void
-gst_wayland_sink_render_last_buffer (GstTizenwlSink * sink)
-{
- FUNCTION_ENTER ();
- g_return_if_fail (sink != NULL);
-
- g_mutex_lock (&sink->render_lock);
- gst_wl_window_set_video_info (sink->window, &sink->video_info);
- sink->video_info_changed = FALSE;
- if (sink->last_buffer)
- render_last_buffer (sink);
- g_mutex_unlock (&sink->render_lock);
-}
-#endif
-static void
-gst_wayland_sink_set_render_rectangle (GstVideoOverlay * overlay,
- gint x, gint y, gint w, gint h)
-{
- FUNCTION_ENTER ();
-
- GstTizenwlSink *sink = GST_WAYLAND_SINK (overlay);
-
- g_return_if_fail (sink != NULL);
-
- g_mutex_lock (&sink->render_lock);
- if (!sink->window) {
- g_mutex_unlock (&sink->render_lock);
- GST_WARNING_OBJECT (sink,
- "set_render_rectangle called without window, ignoring");
- return;
- }
-
- GST_DEBUG_OBJECT (sink, "window geometry changed to (%d, %d) %d x %d",
- x, y, w, h);
- gst_wl_window_set_render_rectangle (sink->window, x, y, w, h);
-
- g_mutex_unlock (&sink->render_lock);
-}
-
-static void
-gst_wayland_sink_expose (GstVideoOverlay * overlay)
-{
- FUNCTION_ENTER ();
-
- GstTizenwlSink *sink = GST_WAYLAND_SINK (overlay);
-
- g_return_if_fail (sink != NULL);
-
- GST_DEBUG_OBJECT (sink, "expose");
-
- g_mutex_lock (&sink->render_lock);
- if (sink->last_buffer && g_atomic_int_get (&sink->redraw_pending) == FALSE) {
- GST_DEBUG_OBJECT (sink, "redrawing last buffer");
- render_last_buffer (sink);
- }
- g_mutex_unlock (&sink->render_lock);
-}
-
-static void
-gst_wayland_sink_waylandvideo_init (GstWaylandVideoInterface * iface)
-{
- FUNCTION_ENTER ();
-
- iface->begin_geometry_change = gst_wayland_sink_begin_geometry_change;
- iface->end_geometry_change = gst_wayland_sink_end_geometry_change;
-}
-
-static void
-gst_wayland_sink_begin_geometry_change (GstWaylandVideo * video)
-{
- FUNCTION_ENTER ();
-
- GstTizenwlSink *sink = GST_WAYLAND_SINK (video);
- g_return_if_fail (sink != NULL);
-
- g_mutex_lock (&sink->render_lock);
- if (!sink->window || !sink->window->subsurface) {
- g_mutex_unlock (&sink->render_lock);
- GST_INFO_OBJECT (sink,
- "begin_geometry_change called without window, ignoring");
- return;
- }
-
- wl_subsurface_set_sync (sink->window->subsurface);
- g_mutex_unlock (&sink->render_lock);
-}
-
-static void
-gst_wayland_sink_end_geometry_change (GstWaylandVideo * video)
-{
- FUNCTION_ENTER ();
-
- GstTizenwlSink *sink = GST_WAYLAND_SINK (video);
- g_return_if_fail (sink != NULL);
-
- g_mutex_lock (&sink->render_lock);
- if (!sink->window || !sink->window->subsurface) {
- g_mutex_unlock (&sink->render_lock);
- GST_INFO_OBJECT (sink,
- "end_geometry_change called without window, ignoring");
- return;
- }
-
- wl_subsurface_set_desync (sink->window->subsurface);
- g_mutex_unlock (&sink->render_lock);
-}
-
-static gboolean
-plugin_init (GstPlugin * plugin)
-{
- FUNCTION_ENTER ();
-
- GST_DEBUG_CATEGORY_INIT (gsttizenwl_debug, "waylandsink", 0,
- " temporary wayland video sink");
-
- return gst_element_register (plugin, "waylandsink", GST_RANK_MARGINAL,
- GST_TYPE_WAYLAND_SINK);
-}
-
-GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
- GST_VERSION_MINOR,
- waylandsink,
- "Temporary Wayland Video Sink", plugin_init, VERSION, "LGPL", GST_PACKAGE_NAME,
- GST_PACKAGE_ORIGIN)
+++ /dev/null
-/*
- * GStreamer Wayland video sink
- * Copyright (C) 2011 Intel Corporation
- * Copyright (C) 2011 Sreerenj Balachandran <sreerenj.balachandran@intel.com>
- *
- * 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., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301 USA.
- */
-
-#ifndef __GST_WAYLAND_VIDEO_SINK_H__
-#define __GST_WAYLAND_VIDEO_SINK_H__
-
-#include <gst/gst.h>
-#include <gst/video/video.h>
-
-#include <wayland-client.h>
-
-#include "wldisplay.h"
-#include "wlwindow.h"
-
-G_BEGIN_DECLS
-#define GST_TYPE_WAYLAND_SINK \
- (gst_wayland_sink_get_type())
-#define GST_WAYLAND_SINK(obj) \
- (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_WAYLAND_SINK,GstTizenwlSink))
-#define GST_WAYLAND_SINK_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_WAYLAND_SINK,GstTizenwlSinkClass))
-#define GST_IS_WAYLAND_SINK(obj) \
- (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_WAYLAND_SINK))
-#define GST_IS_WAYLAND_SINK_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_WAYLAND_SINK))
-#define GST_WAYLAND_SINK_GET_CLASS(inst) \
- (G_TYPE_INSTANCE_GET_CLASS ((inst), GST_TYPE_WAYLAND_SINK, GstTizenwlSinkClass))
-#ifdef GST_WLSINK_ENHANCEMENT
- 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_NUM,
-};
-
-enum
-{
- DEGREE_0,
- DEGREE_90,
- DEGREE_180,
- DEGREE_270,
- DEGREE_NUM,
-};
-
-enum
-{
- FLIP_NONE = 0,
- FLIP_HORIZONTAL,
- FLIP_VERTICAL,
- FLIP_BOTH,
- FLIP_NUM,
-};
-
-#define DEF_DISPLAY_FLIP FLIP_NONE
-#define DEF_DISPLAY_GEOMETRY_METHOD DISP_GEO_METHOD_FULL_SCREEN
-
-#define WL_SCREEN_SIZE_WIDTH 4096
-#define WL_SCREEN_SIZE_HEIGHT 4096
-
-#endif
-#if 1
-#define FUNCTION_ENTER() GST_INFO("<ENTER>")
-#else
-#define FUNCTION_ENTER()
-#endif
-typedef struct _GstTizenwlSink GstTizenwlSink;
-typedef struct _GstTizenwlSinkClass GstTizenwlSinkClass;
-
-struct _GstTizenwlSink
-{
- GstVideoSink parent;
-
- GMutex display_lock;
- GstWlDisplay *display;
- GstWlWindow *window;
- GstBufferPool *pool;
-
- gboolean video_info_changed;
- GstVideoInfo video_info;
-
- /*property */
- gchar *display_name;
-#ifdef GST_WLSINK_ENHANCEMENT
- guint rotate_angle;
- guint display_geometry_method;
- guint orientation;
- guint flip;
- GstCaps *caps;
-#endif
- gboolean redraw_pending;
- GMutex render_lock;
- GstBuffer *last_buffer;
-};
-
-struct _GstTizenwlSinkClass
-{
- GstVideoSinkClass parent;
-};
-
-GType
-gst_wayland_sink_get_type (void)
- G_GNUC_CONST;
-
-G_END_DECLS
-#endif /* __GST_WAYLAND_VIDEO_SINK_H__ */
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<protocol name="scaler">
-
- <copyright>
- Copyright © 2013-2014 Collabora, Ltd.
-
- Permission to use, copy, modify, distribute, and sell this
- software and its documentation for any purpose is hereby granted
- without fee, provided that the above copyright notice appear in
- all copies and that both that copyright notice and this permission
- notice appear in supporting documentation, and that the name of
- the copyright holders not be used in advertising or publicity
- pertaining to distribution of the software without specific,
- written prior permission. The copyright holders make no
- representations about the suitability of this software for any
- purpose. It is provided "as is" without express or implied
- warranty.
-
- THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
- SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
- FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
- SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
- AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
- ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
- THIS SOFTWARE.
- </copyright>
-
- <interface name="wl_scaler" version="2">
- <description summary="surface cropping and scaling">
- The global interface exposing surface cropping and scaling
- capabilities is used to instantiate an interface extension for a
- wl_surface object. This extended interface will then allow
- cropping and scaling the surface contents, effectively
- disconnecting the direct relationship between the buffer and the
- surface size.
- </description>
-
- <request name="destroy" type="destructor">
- <description summary="unbind from the cropping and scaling interface">
- Informs the server that the client will not be using this
- protocol object anymore. This does not affect any other objects,
- wl_viewport objects included.
- </description>
- </request>
-
- <enum name="error">
- <entry name="viewport_exists" value="0"
- summary="the surface already has a viewport object associated"/>
- </enum>
-
- <request name="get_viewport">
- <description summary="extend surface interface for crop and scale">
- Instantiate an interface extension for the given wl_surface to
- crop and scale its content. If the given wl_surface already has
- a wl_viewport object associated, the viewport_exists
- protocol error is raised.
- </description>
-
- <arg name="id" type="new_id" interface="wl_viewport"
- summary="the new viewport interface id"/>
- <arg name="surface" type="object" interface="wl_surface"
- summary="the surface"/>
- </request>
- </interface>
-
- <interface name="wl_viewport" version="2">
- <description summary="crop and scale interface to a wl_surface">
- An additional interface to a wl_surface object, which allows the
- client to specify the cropping and scaling of the surface
- contents.
-
- This interface allows to define the source rectangle (src_x,
- src_y, src_width, src_height) from where to take the wl_buffer
- contents, and scale that to destination size (dst_width,
- dst_height). This state is double-buffered, and is applied on the
- next wl_surface.commit.
-
- The two parts of crop and scale state are independent: the source
- rectangle, and the destination size. Initially both are unset, that
- is, no scaling is applied. The whole of the current wl_buffer is
- used as the source, and the surface size is as defined in
- wl_surface.attach.
-
- If the destination size is set, it causes the surface size to become
- dst_width, dst_height. The source (rectangle) is scaled to exactly
- this size. This overrides whatever the attached wl_buffer size is,
- unless the wl_buffer is NULL. If the wl_buffer is NULL, the surface
- has no content and therefore no size. Otherwise, the size is always
- at least 1x1 in surface coordinates.
-
- If the source rectangle is set, it defines what area of the
- wl_buffer is taken as the source. If the source rectangle is set and
- the destination size is not set, the surface size becomes the source
- rectangle size rounded up to the nearest integer. If the source size
- is already exactly integers, this results in cropping without scaling.
-
- The coordinate transformations from buffer pixel coordinates up to
- the surface-local coordinates happen in the following order:
- 1. buffer_transform (wl_surface.set_buffer_transform)
- 2. buffer_scale (wl_surface.set_buffer_scale)
- 3. crop and scale (wl_viewport.set*)
- This means, that the source rectangle coordinates of crop and scale
- are given in the coordinates after the buffer transform and scale,
- i.e. in the coordinates that would be the surface-local coordinates
- if the crop and scale was not applied.
-
- If the source rectangle is partially or completely outside of the
- wl_buffer, then the surface contents are undefined (not void), and
- the surface size is still dst_width, dst_height.
-
- The x, y arguments of wl_surface.attach are applied as normal to
- the surface. They indicate how many pixels to remove from the
- surface size from the left and the top. In other words, they are
- still in the surface-local coordinate system, just like dst_width
- and dst_height are.
-
- If the wl_surface associated with the wl_viewport is destroyed,
- the wl_viewport object becomes inert.
-
- If the wl_viewport object is destroyed, the crop and scale
- state is removed from the wl_surface. The change will be applied
- on the next wl_surface.commit.
- </description>
-
- <request name="destroy" type="destructor">
- <description summary="remove scaling and cropping from the surface">
- The associated wl_surface's crop and scale state is removed.
- The change is applied on the next wl_surface.commit.
- </description>
- </request>
-
- <enum name="error">
- <entry name="bad_value" value="0"
- summary="negative or zero values in width or height"/>
- </enum>
-
- <request name="set">
- <description summary="set the crop and scale state">
- Set both source rectangle and destination size of the associated
- wl_surface. See wl_viewport for the description, and relation to
- the wl_buffer size.
-
- The bad_value protocol error is raised if src_width or
- src_height is negative, or if dst_width or dst_height is not
- positive.
-
- The crop and scale state is double-buffered state, and will be
- applied on the next wl_surface.commit.
-
- Arguments dst_x and dst_y do not exist here, use the x and y
- arguments to wl_surface.attach. The x, y, dst_width, and dst_height
- define the surface-local coordinate system irrespective of the
- attached wl_buffer size.
- </description>
-
- <arg name="src_x" type="fixed" summary="source rectangle x"/>
- <arg name="src_y" type="fixed" summary="source rectangle y"/>
- <arg name="src_width" type="fixed" summary="source rectangle width"/>
- <arg name="src_height" type="fixed" summary="source rectangle height"/>
- <arg name="dst_width" type="int" summary="surface width"/>
- <arg name="dst_height" type="int" summary="surface height"/>
- </request>
-
- <request name="set_source" since="2">
- <description summary="set the source rectangle for cropping">
- Set the source rectangle of the associated wl_surface. See
- wl_viewport for the description, and relation to the wl_buffer
- size.
-
- If width is -1.0 and height is -1.0, the destination size is unset
- instead. Any other pair of values for width and height that
- contains zero or negative values raises the bad_value protocol
- error.
-
- The crop and scale state is double-buffered state, and will be
- applied on the next wl_surface.commit.
- </description>
-
- <arg name="x" type="fixed" summary="source rectangle x"/>
- <arg name="y" type="fixed" summary="source rectangle y"/>
- <arg name="width" type="fixed" summary="source rectangle width"/>
- <arg name="height" type="fixed" summary="source rectangle height"/>
- </request>
-
- <request name="set_destination" since="2">
- <description summary="set the surface size for scaling">
- Set the destination size of the associated wl_surface. See
- wl_viewport for the description, and relation to the wl_buffer
- size.
-
- If width is -1 and height is -1, the destination size is unset
- instead. Any other pair of values for width and height that
- contains zero or negative values raises the bad_value protocol
- error.
-
- The crop and scale state is double-buffered state, and will be
- applied on the next wl_surface.commit.
-
- Arguments x and y do not exist here, use the x and y arguments to
- wl_surface.attach. The x, y, width, and height define the
- surface-local coordinate system irrespective of the attached
- wl_buffer size.
- </description>
-
- <arg name="width" type="int" summary="surface width"/>
- <arg name="height" type="int" summary="surface height"/>
- </request>
- </interface>
-</protocol>
+++ /dev/null
-/* GStreamer Wayland video sink
- *
- * Copyright (C) 2011 Intel Corporation
- * Copyright (C) 2011 Sreerenj Balachandran <sreerenj.balachandran@intel.com>
- * Copyright (C) 2012 Wim Taymans <wim.taymans@gmail.com>
- * Copyright (C) 2014 Collabora Ltd.
- *
- * 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., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301 USA.
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-#include "tizen-wlvideoformat.h"
-#ifdef GST_WLSINK_ENHANCEMENT
-
-GST_DEBUG_CATEGORY_EXTERN (gsttizenwl_debug);
-#define GST_CAT_DEFAULT gsttizenwl_debug
-
-typedef struct
-{
- uint32_t wl_format;
- GstVideoFormat gst_format;
-} wl_VideoFormat;
-
-static const wl_VideoFormat formats[] = {
-#if G_BYTE_ORDER == G_BIG_ENDIAN
- {TBM_FORMAT_XRGB8888, GST_VIDEO_FORMAT_xRGB},
- {TBM_FORMAT_XBGR8888, GST_VIDEO_FORMAT_xBGR},
- {TBM_FORMAT_RGBX8888, GST_VIDEO_FORMAT_RGBx},
- {TBM_FORMAT_BGRX8888, GST_VIDEO_FORMAT_BGRx},
- {TBM_FORMAT_ARGB8888, GST_VIDEO_FORMAT_ARGB},
- {TBM_FORMAT_ABGR8888, GST_VIDEO_FORMAT_RGBA},
- {TBM_FORMAT_RGBA8888, GST_VIDEO_FORMAT_RGBA},
- {TBM_FORMAT_BGRA8888, GST_VIDEO_FORMAT_BGRA},
-#else
- {TBM_FORMAT_XRGB8888, GST_VIDEO_FORMAT_BGRx},
- {TBM_FORMAT_XBGR8888, GST_VIDEO_FORMAT_RGBx},
- {TBM_FORMAT_RGBX8888, GST_VIDEO_FORMAT_xBGR},
- {TBM_FORMAT_BGRX8888, GST_VIDEO_FORMAT_xRGB},
- {TBM_FORMAT_ARGB8888, GST_VIDEO_FORMAT_BGRA},
- {TBM_FORMAT_ABGR8888, GST_VIDEO_FORMAT_RGBA},
- {TBM_FORMAT_RGBA8888, GST_VIDEO_FORMAT_ABGR},
- {TBM_FORMAT_BGRA8888, GST_VIDEO_FORMAT_ARGB},
-#endif
- {TBM_FORMAT_RGB565, GST_VIDEO_FORMAT_RGB16},
- {TBM_FORMAT_BGR565, GST_VIDEO_FORMAT_BGR16},
- {TBM_FORMAT_RGB888, GST_VIDEO_FORMAT_RGB},
- {TBM_FORMAT_BGR888, GST_VIDEO_FORMAT_BGR},
- {TBM_FORMAT_YUYV, GST_VIDEO_FORMAT_YUY2},
- {TBM_FORMAT_YVYU, GST_VIDEO_FORMAT_YVYU},
- {TBM_FORMAT_UYVY, GST_VIDEO_FORMAT_UYVY},
- {TBM_FORMAT_AYUV, GST_VIDEO_FORMAT_AYUV},
- {TBM_FORMAT_NV12, GST_VIDEO_FORMAT_NV12},
- {TBM_FORMAT_NV21, GST_VIDEO_FORMAT_NV21},
- {TBM_FORMAT_NV16, GST_VIDEO_FORMAT_NV16},
- {TBM_FORMAT_YUV410, GST_VIDEO_FORMAT_YUV9},
- {TBM_FORMAT_YVU410, GST_VIDEO_FORMAT_YVU9},
- {TBM_FORMAT_YUV411, GST_VIDEO_FORMAT_Y41B},
- {TBM_FORMAT_YUV420, GST_VIDEO_FORMAT_I420},
- {TBM_FORMAT_YVU420, GST_VIDEO_FORMAT_YV12},
- {TBM_FORMAT_YUV422, GST_VIDEO_FORMAT_Y42B},
- {TBM_FORMAT_YUV444, GST_VIDEO_FORMAT_v308},
- {TBM_FORMAT_NV12MT, GST_VIDEO_FORMAT_ST12},
- {TBM_FORMAT_NV12, GST_VIDEO_FORMAT_SN12},
-};
-
-uint32_t
-gst_video_format_to_wayland_format (GstVideoFormat format)
-{
- guint i;
-
- for (i = 0; i < G_N_ELEMENTS (formats); i++)
- if (formats[i].gst_format == format)
- return formats[i].wl_format;
-
- GST_WARNING ("wayland video format not found");
- return -1;
-}
-
-GstVideoFormat
-gst_wayland_format_to_video_format (uint32_t wl_format)
-{
- guint i;
-
- for (i = 0; i < G_N_ELEMENTS (formats); i++)
- if (formats[i].wl_format == wl_format)
- return formats[i].gst_format;
-
- GST_WARNING ("gst video format not found");
- return GST_VIDEO_FORMAT_UNKNOWN;
-}
-
-const gchar *
-gst_wayland_format_to_string (uint32_t wl_format)
-{
- return gst_video_format_to_string
- (gst_wayland_format_to_video_format (wl_format));
-}
-#endif
+++ /dev/null
-/* GStreamer Wayland video sink
- *
- * Copyright (C) 2011 Intel Corporation
- * Copyright (C) 2011 Sreerenj Balachandran <sreerenj.balachandran@intel.com>
- * Copyright (C) 2012 Wim Taymans <wim.taymans@gmail.com>
- * Copyright (C) 2014 Collabora Ltd.
- *
- * 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., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301 USA.
- */
-
-#ifndef __GST_TIZEN_WL_VIDEO_FORMAT_H__
-#define __GST_TIZEN_WL_VIDEO_FORMAT_H__
-
-#include <wayland-client.h>
-#include <gst/video/video.h>
-
-#ifdef GST_WLSINK_ENHANCEMENT
-#include <tbm_surface.h>
-
-G_BEGIN_DECLS
- uint32_t gst_video_format_to_wayland_format (GstVideoFormat format);
-GstVideoFormat gst_wayland_format_to_video_format (uint32_t wl_format);
-
-const gchar *gst_wayland_format_to_string (uint32_t wl_format);
-
-G_END_DECLS
-#endif
-#endif
+++ /dev/null
-/* GStreamer
- * Copyright (C) 2012 Intel Corporation
- * Copyright (C) 2012 Sreerenj Balachandran <sreerenj.balachandran@intel.com>
- * Copyright (C) 2014 Collabora Ltd.
- *
- * 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., 51 Franklin St, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "waylandpool.h"
-#include "wldisplay.h"
-#include "wlvideoformat.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <unistd.h>
-#include <sys/mman.h>
-#include <sys/types.h>
-#ifdef GST_WLSINK_ENHANCEMENT
-//#define DUMP_BUFFER
-#ifdef DUMP_BUFFER
-int dump_cnt = 0;
-int _write_rawdata (const char *file, const void *data, unsigned int size);
-#endif
-#endif
-
-GST_DEBUG_CATEGORY_EXTERN (gsttizenwl_debug);
-#define GST_CAT_DEFAULT gsttizenwl_debug
-
-/* wl metadata */
-GType
-gst_wl_meta_api_get_type (void)
-{
- static volatile GType type;
- static const gchar *tags[] =
- { "memory", "size", "colorspace", "orientation", NULL };
-
- if (g_once_init_enter (&type)) {
- GType _type = gst_meta_api_type_register ("GstWlMetaAPI", tags);
- g_once_init_leave (&type, _type);
- }
- return type;
-}
-
-static void
-gst_wl_meta_free (GstWlMeta * meta, GstBuffer * buffer)
-{
-#ifdef GST_WLSINK_ENHANCEMENT
- if (!meta || !meta->pool)
- return;
- if (meta->tsurface)
- tbm_surface_destroy (meta->tsurface);
- g_hash_table_remove (meta->pool->buffers_map, meta->wbuffer);
-#endif
- GST_DEBUG ("destroying wl_buffer %p", meta->wbuffer);
- wl_buffer_destroy (meta->wbuffer);
-}
-
-const GstMetaInfo *
-gst_wl_meta_get_info (void)
-{
- static const GstMetaInfo *wl_meta_info = NULL;
-
- if (g_once_init_enter (&wl_meta_info)) {
- const GstMetaInfo *meta =
- gst_meta_register (GST_WL_META_API_TYPE, "GstWlMeta",
- sizeof (GstWlMeta), (GstMetaInitFunction) NULL,
- (GstMetaFreeFunction) gst_wl_meta_free,
- (GstMetaTransformFunction) NULL);
- g_once_init_leave (&wl_meta_info, meta);
- }
- return wl_meta_info;
-}
-
-/* bufferpool */
-static void gst_wayland_buffer_pool_finalize (GObject * object);
-static gboolean gst_wayland_buffer_pool_set_config (GstBufferPool * pool,
- GstStructure * config);
-static gboolean gst_wayland_buffer_pool_start (GstBufferPool * pool);
-static gboolean gst_wayland_buffer_pool_stop (GstBufferPool * pool);
-static GstFlowReturn gst_wayland_buffer_pool_alloc (GstBufferPool * pool,
- GstBuffer ** buffer, GstBufferPoolAcquireParams * params);
-
-#ifdef GST_WLSINK_ENHANCEMENT
-/*tizen buffer pool*/
-static void gst_wayland_tizen_buffer_pool_finalize (GObject * object);
-static gboolean gst_wayland_tizen_buffer_pool_start (GstBufferPool * pool);
-static gboolean gst_wayland_tizen_buffer_pool_stop (GstBufferPool * pool);
-static GstFlowReturn gst_wayland_tizen_buffer_pool_alloc (GstBufferPool * pool,
- GstBuffer ** buffer, GstBufferPoolAcquireParams * params);
-void gst_wayland_buffer_pool_remove_displaying_buffer (GstWaylandBufferPool *
- self, struct wl_buffer *wl_buffer);
-#endif
-
-#define gst_wayland_buffer_pool_parent_class parent_class
-G_DEFINE_TYPE (GstWaylandBufferPool, gst_wayland_buffer_pool,
- GST_TYPE_BUFFER_POOL);
-
-static void
-gst_wayland_buffer_pool_class_init (GstWaylandBufferPoolClass * klass)
-{
- FUNCTION_ENTER ();
-
- GObjectClass *gobject_class = (GObjectClass *) klass;
- GstBufferPoolClass *gstbufferpool_class = (GstBufferPoolClass *) klass;
-
- gstbufferpool_class->set_config = gst_wayland_buffer_pool_set_config;
-#ifdef GST_WLSINK_ENHANCEMENT
- gobject_class->finalize = gst_wayland_tizen_buffer_pool_finalize;
- gstbufferpool_class->start = gst_wayland_tizen_buffer_pool_start;
- gstbufferpool_class->alloc_buffer = gst_wayland_tizen_buffer_pool_alloc;
-#else
- gobject_class->finalize = gst_wayland_buffer_pool_finalize;
- gstbufferpool_class->start = gst_wayland_buffer_pool_start;
- gstbufferpool_class->stop = gst_wayland_buffer_pool_stop;
- gstbufferpool_class->alloc_buffer = gst_wayland_buffer_pool_alloc;
-#endif
-}
-
-static void
-gst_wayland_buffer_pool_init (GstWaylandBufferPool * self)
-{
- FUNCTION_ENTER ();
-
- gst_video_info_init (&self->info);
- g_mutex_init (&self->buffers_map_mutex);
- self->buffers_map = g_hash_table_new (g_direct_hash, g_direct_equal);
-
- g_mutex_init (&self->displaying_buffers_map_mutex);
- self->displaying_buffers_map =
- g_hash_table_new (g_direct_hash, g_direct_equal);
-}
-
-static void
-gst_wayland_buffer_pool_finalize (GObject * object)
-{
- FUNCTION_ENTER ();
-
- GstWaylandBufferPool *pool = GST_WAYLAND_BUFFER_POOL_CAST (object);
-
- if (pool->wl_pool)
- gst_wayland_buffer_pool_stop (GST_BUFFER_POOL (pool));
-
- g_mutex_clear (&pool->buffers_map_mutex);
- g_hash_table_unref (pool->buffers_map);
-
- g_mutex_clear (&pool->displaying_buffers_map_mutex);
- g_hash_table_unref (pool->displaying_buffers_map);
-
- g_object_unref (pool->display);
-
- G_OBJECT_CLASS (gst_wayland_buffer_pool_parent_class)->finalize (object);
-}
-
-static void
-buffer_release (void *data, struct wl_buffer *wl_buffer)
-{
- FUNCTION_ENTER ();
-
- GstWaylandBufferPool *self = data;
- GstBuffer *buffer;
- GstWlMeta *meta;
-
- g_mutex_lock (&self->buffers_map_mutex);
-
-#ifdef GST_WLSINK_ENHANCEMENT
- /*remove displaying buffer */
- if (self->display->is_native_format == TRUE)
- gst_wayland_buffer_pool_remove_displaying_buffer (self, wl_buffer);
-#endif
- buffer = g_hash_table_lookup (self->buffers_map, wl_buffer);
-
- GST_LOG_OBJECT (self, "wl_buffer::release (GstBuffer: %p)", buffer);
-
- if (buffer) {
- meta = gst_buffer_get_wl_meta (buffer);
- if (meta->used_by_compositor) {
- meta->used_by_compositor = FALSE;
- /* unlock before unref because stop() may be called from here */
- GST_LOG_OBJECT (self, "Decrease ref count of buffer");
- gst_buffer_unref (buffer);
- }
- }
- g_mutex_unlock (&self->buffers_map_mutex);
-}
-
-static const struct wl_buffer_listener buffer_listener = {
- buffer_release
-};
-
-void
-gst_wayland_compositor_acquire_buffer (GstWaylandBufferPool * self,
- GstBuffer * buffer)
-{
- FUNCTION_ENTER ();
-
- GstWlMeta *meta;
-
- meta = gst_buffer_get_wl_meta (buffer);
- g_return_if_fail (meta != NULL);
- g_return_if_fail (meta->pool == self);
- g_return_if_fail (meta->used_by_compositor == FALSE);
-
- meta->used_by_compositor = TRUE;
- GST_LOG_OBJECT (self, "Increase ref count of buffer");
- gst_buffer_ref (buffer);
-}
-
-static void
-unref_used_buffers (gpointer key, gpointer value, gpointer data)
-{
- FUNCTION_ENTER ();
-
- GstBuffer *buffer = value;
- GstWlMeta *meta = gst_buffer_get_wl_meta (buffer);
- GList **to_unref = data;
-
- if (meta == NULL)
- return;
-
- if (meta->used_by_compositor) {
- meta->used_by_compositor = FALSE;
- *to_unref = g_list_prepend (*to_unref, buffer);
- }
-}
-
-void
-gst_wayland_compositor_release_all_buffers (GstWaylandBufferPool * self)
-{
- FUNCTION_ENTER ();
-
- GList *to_unref = NULL;
-
- g_mutex_lock (&self->buffers_map_mutex);
- g_hash_table_foreach (self->buffers_map, unref_used_buffers, &to_unref);
-
- if (to_unref) {
- g_list_free_full (to_unref, (GDestroyNotify) gst_buffer_unref);
- }
- g_mutex_unlock (&self->buffers_map_mutex);
-}
-
-static gboolean
-gst_wayland_buffer_pool_set_config (GstBufferPool * pool, GstStructure * config)
-{
- FUNCTION_ENTER ();
-
- GstWaylandBufferPool *self = GST_WAYLAND_BUFFER_POOL_CAST (pool);
- GstCaps *caps;
-
- if (!gst_buffer_pool_config_get_params (config, &caps, NULL, NULL, NULL))
- goto wrong_config;
-
- if (caps == NULL)
- goto no_caps;
-
- /* now parse the caps from the config */
- if (!gst_video_info_from_caps (&self->info, caps))
- goto wrong_caps;
-
- GST_LOG_OBJECT (pool, "%dx%d, caps %" GST_PTR_FORMAT,
- GST_VIDEO_INFO_WIDTH (&self->info), GST_VIDEO_INFO_HEIGHT (&self->info),
- caps);
-
- /*Fixme: Enable metadata checking handling based on the config of pool */
-
- return GST_BUFFER_POOL_CLASS (parent_class)->set_config (pool, config);
- /* ERRORS */
-wrong_config:
- {
- GST_WARNING_OBJECT (pool, "invalid config");
- return FALSE;
- }
-no_caps:
- {
- GST_WARNING_OBJECT (pool, "no caps in config");
- return FALSE;
- }
-wrong_caps:
- {
- GST_WARNING_OBJECT (pool,
- "failed getting geometry from caps %" GST_PTR_FORMAT, caps);
- return FALSE;
- }
-}
-
-static gboolean
-gst_wayland_buffer_pool_start (GstBufferPool * pool)
-{
- FUNCTION_ENTER ();
-
- GstWaylandBufferPool *self = GST_WAYLAND_BUFFER_POOL (pool);
-
- GST_DEBUG_OBJECT (self, "Initializing wayland buffer pool");
-
- guint size = 0;
- int fd;
- char filename[1024];
- static int init = 0;
-
- GST_DEBUG_OBJECT (self, "Initializing wayland buffer pool");
-
- /* configure */
- size = GST_VIDEO_INFO_SIZE (&self->info) * 15;
-
- /* allocate shm pool */
- snprintf (filename, 1024, "%s/%s-%d-%s", g_get_user_runtime_dir (),
- "wayland-shm", init++, "XXXXXX");
-
- fd = mkstemp (filename);
- if (fd < 0) {
- GST_ERROR_OBJECT (pool, "opening temp file %s failed: %s", filename,
- strerror (errno));
- return FALSE;
- }
- if (ftruncate (fd, size) < 0) {
- GST_ERROR_OBJECT (pool, "ftruncate failed: %s", strerror (errno));
- close (fd);
- return FALSE;
- }
-
- self->data = mmap (NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
- if (self->data == MAP_FAILED) {
- GST_ERROR_OBJECT (pool, "mmap failed: %s", strerror (errno));
- close (fd);
- return FALSE;
- }
-
- self->wl_pool = wl_shm_create_pool (self->display->shm, fd, size);
- unlink (filename);
- close (fd);
-
- self->size = size;
- self->used = 0;
-
-
- return GST_BUFFER_POOL_CLASS (parent_class)->start (pool);
-}
-
-static gboolean
-gst_wayland_buffer_pool_stop (GstBufferPool * pool)
-{
- FUNCTION_ENTER ();
-
- GstWaylandBufferPool *self = GST_WAYLAND_BUFFER_POOL (pool);
-
- GST_DEBUG_OBJECT (self, "Stopping wayland buffer pool");
-
- munmap (self->data, self->size);
- wl_shm_pool_destroy (self->wl_pool);
-
- self->wl_pool = NULL;
- self->size = 0;
- self->used = 0;
-
- /* all buffers are about to be destroyed;
- * we should no longer do anything with them */
- g_mutex_lock (&self->buffers_map_mutex);
- g_hash_table_remove_all (self->buffers_map);
- g_mutex_unlock (&self->buffers_map_mutex);
-
- return GST_BUFFER_POOL_CLASS (parent_class)->stop (pool);
-}
-
-static GstFlowReturn
-gst_wayland_buffer_pool_alloc (GstBufferPool * pool, GstBuffer ** buffer,
- GstBufferPoolAcquireParams * params)
-{
- FUNCTION_ENTER ();
-
- GstWaylandBufferPool *self = GST_WAYLAND_BUFFER_POOL_CAST (pool);
-
- gint width, height, stride;
- gsize size;
- enum wl_shm_format format;
- gint offset;
- void *data;
- GstWlMeta *meta;
-
- width = GST_VIDEO_INFO_WIDTH (&self->info);
- height = GST_VIDEO_INFO_HEIGHT (&self->info);
- stride = GST_VIDEO_INFO_PLANE_STRIDE (&self->info, 0);
- size = GST_VIDEO_INFO_SIZE (&self->info);
- format =
- gst_video_format_to_wayland_format (GST_VIDEO_INFO_FORMAT (&self->info));
-
- GST_DEBUG_OBJECT (self, "Allocating buffer of size %" G_GSSIZE_FORMAT
- " (%d x %d, stride %d), format %s", size, width, height, stride,
- gst_wayland_format_to_string (format));
- /* try to reserve another memory block from the shm pool */
- if (self->used + size > self->size)
- goto no_buffer;
-
- offset = self->used;
- self->used += size;
-
- data = ((gchar *) self->data) + offset;
-
- /* create buffer and its metadata object */
- *buffer = gst_buffer_new ();
- meta = (GstWlMeta *) gst_buffer_add_meta (*buffer, GST_WL_META_INFO, NULL);
- meta->pool = self;
-
- meta->wbuffer = wl_shm_pool_create_buffer (self->wl_pool, offset,
- width, height, stride, format);
- meta->used_by_compositor = FALSE;
-
- /* configure listening to wl_buffer.release */
- g_mutex_lock (&self->buffers_map_mutex);
- g_hash_table_insert (self->buffers_map, meta->wbuffer, *buffer);
- g_mutex_unlock (&self->buffers_map_mutex);
-
- wl_buffer_add_listener (meta->wbuffer, &buffer_listener, self);
-
- /* add the allocated memory on the GstBuffer */
- gst_buffer_append_memory (*buffer,
- gst_memory_new_wrapped (GST_MEMORY_FLAG_NO_SHARE, data,
- size, 0, size, NULL, NULL));
-
- return GST_FLOW_OK;
-
- /* ERROR */
-no_buffer:
- {
- GST_WARNING_OBJECT (pool, "can't create buffer");
- return GST_FLOW_ERROR;
- }
-}
-
-GstBufferPool *
-gst_wayland_buffer_pool_new (GstWlDisplay * display)
-{
- FUNCTION_ENTER ();
-
- GstWaylandBufferPool *pool;
-
- g_return_val_if_fail (GST_IS_WL_DISPLAY (display), NULL);
- pool = g_object_new (GST_TYPE_WAYLAND_BUFFER_POOL, NULL);
- pool->display = g_object_ref (display);
-
- return GST_BUFFER_POOL_CAST (pool);
-}
-
-#ifdef GST_WLSINK_ENHANCEMENT
-
-static gboolean
-gst_wayland_tizen_buffer_pool_start (GstBufferPool * pool)
-{
- FUNCTION_ENTER ();
-
- GstWaylandBufferPool *self = GST_WAYLAND_BUFFER_POOL (pool);
-
- GST_DEBUG_OBJECT (self, "Initializing tizen buffer pool");
-
- tbm_bo_handle vitual_addr;
- guint size = 0;
-
- if (self->display->is_native_format == TRUE) {
- /*in case of SN12 or ST12 video format */
- size = self->display->native_video_size * 15;
- vitual_addr.ptr = NULL;
-
- } else {
- /*in case of normal video format */
- size = GST_VIDEO_INFO_SIZE (&self->info) * 15;
-
- self->display->tbm_bufmgr =
- wayland_tbm_client_get_bufmgr (self->display->tbm_client);
- g_return_if_fail (self->display->tbm_bufmgr != NULL);
-
- self->display->tbm_bo =
- tbm_bo_alloc (self->display->tbm_bufmgr, size, TBM_BO_DEFAULT);
- if (!self->display->tbm_bo) {
- GST_ERROR_OBJECT (pool, "alloc tbm bo(size:%d) failed: %s", size,
- strerror (errno));
- return FALSE;
- }
-
- vitual_addr = tbm_bo_get_handle (self->display->tbm_bo, TBM_DEVICE_CPU);
- if (!vitual_addr.ptr) {
- GST_ERROR_OBJECT (pool, "get tbm bo handle failed: %s", strerror (errno));
- tbm_bo_unref (self->display->tbm_bo);
- self->display->tbm_bo = NULL;
- return FALSE;
- }
- }
-
- self->data = vitual_addr.ptr;
- self->size = size;
- self->used = 0;
-
- return GST_BUFFER_POOL_CLASS (parent_class)->start (pool);
-}
-
-static gboolean
-gst_wayland_tizen_buffer_pool_stop (GstBufferPool * pool)
-{
- FUNCTION_ENTER ();
-
- GstWaylandBufferPool *self = GST_WAYLAND_BUFFER_POOL (pool);
-
- GST_DEBUG_OBJECT (self, "Stopping tizen buffer pool");
-
- self->size = 0;
- self->used = 0;
-
- self->display->tbm_bufmgr = NULL;
-
- /* all buffers are about to be destroyed;
- * we should no longer do anything with them */
- g_mutex_lock (&self->buffers_map_mutex);
- g_hash_table_remove_all (self->buffers_map);
- g_mutex_unlock (&self->buffers_map_mutex);
-
- g_mutex_lock (&self->displaying_buffers_map_mutex);
- g_hash_table_remove_all (self->displaying_buffers_map);
- g_mutex_unlock (&self->displaying_buffers_map_mutex);
-
- return GST_BUFFER_POOL_CLASS (parent_class)->stop (pool);
-}
-
-static GstFlowReturn
-gst_wayland_tizen_buffer_pool_alloc (GstBufferPool * pool, GstBuffer ** buffer,
- GstBufferPoolAcquireParams * params)
-{
- FUNCTION_ENTER ();
-
- GstWaylandBufferPool *self = GST_WAYLAND_BUFFER_POOL_CAST (pool);
-
- gint width, height;
- gsize size;
- uint32_t format;
- gint data_offset;
- void *data;
- GstWlMeta *meta;
- tbm_bo_handle vitual_addr;
- tbm_surface_info_s info;
- int num_bo;
-
- if (self->display->is_native_format == TRUE) {
- /*in case of SN12 or ST12 video format */
- width = GST_VIDEO_INFO_WIDTH (&self->info);
- height = GST_VIDEO_INFO_HEIGHT (&self->info);
- size = self->display->native_video_size;
-
- format =
- gst_video_format_to_wayland_format (GST_VIDEO_INFO_FORMAT
- (&self->info));
-
-
- vitual_addr = tbm_bo_get_handle (self->display->bo[0], TBM_DEVICE_CPU);
- if (!vitual_addr.ptr) {
- GST_ERROR_OBJECT (pool, "get tbm bo handle failed: %s", strerror (errno));
- return FALSE;
- }
- self->data = vitual_addr.ptr;
- data = ((gchar *) self->data);
-#ifdef DUMP_BUFFER
- int ret;
- char file_name[128];
- if (dump_cnt < 10) {
- sprintf (file_name, "/root/WLSINK_OUT_DUMP_%2.2d.dump", dump_cnt++);
- ret = _write_rawdata (file_name, vitual_addr.ptr, size);
- if (ret) {
- GST_ERROR_OBJECT (pool, "_write_rawdata() failed");
- }
- }
-#endif
- /* create buffer and its metadata object */
- *buffer = gst_buffer_new ();
- meta = (GstWlMeta *) gst_buffer_add_meta (*buffer, GST_WL_META_INFO, NULL);
- meta->pool = self;
- GST_DEBUG ("TBM bo %p %p %p", self->display->bo[0],
- self->display->bo[1], 0);
-
- info.width = width;
- info.height = height;
- info.format = format;
- info.bpp = tbm_surface_internal_get_bpp (info.format);
- info.num_planes = tbm_surface_internal_get_num_planes (info.format);
- info.planes[0].stride = self->display->stride_width[0];
- info.planes[1].stride = self->display->stride_width[1];
- info.planes[0].offset = 0;
- info.planes[1].offset =
- (self->display->bo[1]) ? 0 : self->display->plane_size[0];
- num_bo = (self->display->bo[1]) ? 2 : 1;
-
- meta->tsurface =
- tbm_surface_internal_create_with_bos (&info, self->display->bo, num_bo);
- meta->wbuffer =
- wayland_tbm_client_create_buffer (self->display->tbm_client,
- meta->tsurface);
- wl_proxy_set_queue ((struct wl_proxy *) meta->wbuffer,
- self->display->queue);
- meta->used_by_compositor = FALSE;
-
- GST_DEBUG ("tizen_buffer_pool_create_planar_buffer create wl_buffer %p",
- meta->wbuffer);
- } else {
- int stride;
-
- /*in case of normal video format */
- width = GST_VIDEO_INFO_WIDTH (&self->info);
- height = GST_VIDEO_INFO_HEIGHT (&self->info);
- stride = GST_VIDEO_INFO_PLANE_STRIDE (&self->info, 0);
- size = GST_VIDEO_INFO_SIZE (&self->info);
- format =
- gst_video_format_to_wayland_format (GST_VIDEO_INFO_FORMAT
- (&self->info));
-
- GST_DEBUG_OBJECT (self, "Allocating buffer of size %" G_GSSIZE_FORMAT
- " (%d x %d, stride %d), format %s", size, width, height, stride,
- gst_wayland_format_to_string (format));
-
- /* try to reserve another memory block from the shm pool */
- if (self->used + size > self->size)
- goto no_buffer;
-
- data_offset = self->used;
- self->used += size;
-
- data = ((gchar *) self->data) + data_offset;
-
- /* create buffer and its metadata object */
- *buffer = gst_buffer_new ();
- meta = (GstWlMeta *) gst_buffer_add_meta (*buffer, GST_WL_META_INFO, NULL);
- meta->pool = self;
-
- info.width = width;
- info.height = height;
- info.format = format;
- info.bpp = tbm_surface_internal_get_bpp (info.format);
- info.num_planes = tbm_surface_internal_get_num_planes (info.format);
- info.planes[0].stride = GST_VIDEO_INFO_PLANE_STRIDE (&self->info, 0);
- info.planes[1].stride = GST_VIDEO_INFO_PLANE_STRIDE (&self->info, 1);
- info.planes[2].stride = GST_VIDEO_INFO_PLANE_STRIDE (&self->info, 2);
- info.planes[0].offset = GST_VIDEO_INFO_PLANE_OFFSET (&self->info, 0);
- info.planes[1].offset = GST_VIDEO_INFO_PLANE_OFFSET (&self->info, 1);
- info.planes[2].offset = GST_VIDEO_INFO_PLANE_OFFSET (&self->info, 2);
-
- meta->tsurface =
- tbm_surface_internal_create_with_bos (&info, &self->display->tbm_bo, 1);
- meta->wbuffer =
- wayland_tbm_client_create_buffer (self->display->tbm_client,
- meta->tsurface);
- wl_proxy_set_queue ((struct wl_proxy *) meta->wbuffer,
- self->display->queue);
- meta->used_by_compositor = FALSE;
- }
-
- /* configure listening to wl_buffer.release */
- g_mutex_lock (&self->buffers_map_mutex);
- g_hash_table_insert (self->buffers_map, meta->wbuffer, *buffer);
- g_mutex_unlock (&self->buffers_map_mutex);
-
- wl_buffer_add_listener (meta->wbuffer, &buffer_listener, self);
-
- /* add the allocated memory on the GstBuffer */
- gst_buffer_append_memory (*buffer,
- gst_memory_new_wrapped (GST_MEMORY_FLAG_NO_SHARE, data,
- size, 0, size, NULL, NULL));
- return GST_FLOW_OK;
-
- /* ERROR */
-no_buffer:
- {
- GST_WARNING_OBJECT (pool, "can't create buffer");
- return GST_FLOW_ERROR;
- }
-}
-
-static void
-gst_wayland_tizen_buffer_pool_finalize (GObject * object)
-{
- FUNCTION_ENTER ();
-
- GstWaylandBufferPool *pool = GST_WAYLAND_BUFFER_POOL_CAST (object);
-
- if (pool->display->tbm_bufmgr) {
- gst_wayland_tizen_buffer_pool_stop (GST_BUFFER_POOL (pool));
- } else {
- /*already stop */
- return;
- }
- g_mutex_clear (&pool->buffers_map_mutex);
- g_hash_table_unref (pool->buffers_map);
-
- g_mutex_clear (&pool->displaying_buffers_map_mutex);
- g_hash_table_unref (pool->displaying_buffers_map);
-
- g_object_unref (pool->display);
-
- G_OBJECT_CLASS (gst_wayland_buffer_pool_parent_class)->finalize (object);
-}
-
-void
-gst_wayland_buffer_pool_add_displaying_buffer (GstBufferPool * pool,
- GstWlMeta * meta, GstBuffer * buffer)
-{
- FUNCTION_ENTER ();
- g_return_val_if_fail (pool, NULL);
- g_return_val_if_fail (meta, NULL);
- g_return_val_if_fail (buffer, NULL);
-
- GstWaylandBufferPool *self = GST_WAYLAND_BUFFER_POOL_CAST (pool);
-
- g_mutex_lock (&self->displaying_buffers_map_mutex);
-
- GST_LOG_OBJECT (self, "key value is meta->wbuffer(%p)", meta->wbuffer);
- GST_LOG_OBJECT (self, "Increase ref count of buffer(%p) from omx", buffer);
- gst_buffer_ref (buffer);
- g_hash_table_insert (self->displaying_buffers_map, meta->wbuffer, buffer);
-
- g_mutex_unlock (&self->displaying_buffers_map_mutex);
-}
-
-void
-gst_wayland_buffer_pool_remove_displaying_buffer (GstWaylandBufferPool * self,
- struct wl_buffer *wl_buffer)
-{
- FUNCTION_ENTER ();
- g_return_val_if_fail (self, NULL);
- g_return_val_if_fail (wl_buffer, NULL);
-
- GstBuffer *buffer;
- g_mutex_lock (&self->displaying_buffers_map_mutex);
- buffer = g_hash_table_lookup (self->displaying_buffers_map, wl_buffer);
- if (buffer) {
- GST_LOG_OBJECT (self, "Decrease ref count of buffer(%p) from omx", buffer);
- g_hash_table_remove (self->displaying_buffers_map, wl_buffer);
- gst_buffer_unref (buffer);
- }
- g_mutex_unlock (&self->displaying_buffers_map_mutex);
-}
-#endif
-#ifdef DUMP_BUFFER
-int
-_write_rawdata (const char *file, const void *data, unsigned int size)
-{
- FILE *fp;
-
- fp = fopen (file, "wb");
- if (fp == NULL)
- return -1;
-
- fwrite ((char *) data, sizeof (char), size, fp);
- fclose (fp);
-
- return 0;
-}
-#endif
+++ /dev/null
-/* GStreamer Wayland buffer pool
- * Copyright (C) 2012 Intel Corporation
- * Copyright (C) 2012 Sreerenj Balachandran <sreerenj.balachandran@intel.com>
- * Copyright (C) 2014 Collabora Ltd.
- *
- * 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., 51 Franklin St, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-#ifndef __GST_WAYLAND_BUFFER_POOL_H__
-#define __GST_WAYLAND_BUFFER_POOL_H__
-
-#include <gst/video/video.h>
-#include <gst/video/gstvideometa.h>
-
-#include "wldisplay.h"
-#ifdef GST_WLSINK_ENHANCEMENT
-#include <tbm_bufmgr.h>
-#include <tbm_surface.h>
-#include <tbm_surface_internal.h>
-#endif
-
-G_BEGIN_DECLS
-#define GST_TYPE_WAYLAND_BUFFER_POOL (gst_wayland_buffer_pool_get_type())
-#define GST_IS_WAYLAND_BUFFER_POOL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_WAYLAND_BUFFER_POOL))
-#define GST_WAYLAND_BUFFER_POOL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_WAYLAND_BUFFER_POOL, GstWaylandBufferPool))
-#define GST_WAYLAND_BUFFER_POOL_CAST(obj) ((GstWaylandBufferPool*)(obj))
-#if 1
-#define FUNCTION_ENTER() GST_INFO("<ENTER>")
-#else
-#define FUNCTION_ENTER()
-#endif
-typedef struct _GstWaylandBufferPool GstWaylandBufferPool;
-typedef struct _GstWaylandBufferPoolClass GstWaylandBufferPoolClass;
-
-/* buffer meta */
-typedef struct _GstWlMeta GstWlMeta;
-
-GType gst_wl_meta_api_get_type (void);
-#define GST_WL_META_API_TYPE (gst_wl_meta_api_get_type())
-
-const GstMetaInfo *gst_wl_meta_get_info (void);
-#define GST_WL_META_INFO (gst_wl_meta_get_info())
-
-#define gst_buffer_get_wl_meta(b) ((GstWlMeta*)gst_buffer_get_meta((b),GST_WL_META_API_TYPE))
-
-struct _GstWlMeta
-{
- GstMeta meta;
-
- GstWaylandBufferPool *pool;
- struct wl_buffer *wbuffer;
- gboolean used_by_compositor;
-#ifdef GST_WLSINK_ENHANCEMENT
- tbm_surface_h tsurface;
-#endif
-};
-
-/* buffer pool */
-struct _GstWaylandBufferPool
-{
- GstBufferPool bufferpool;
- GstWlDisplay *display;
-
- /* external configuration */
- GstVideoInfo info;
-
- /* allocation data */
- struct wl_shm_pool *wl_pool;
- size_t size;
- size_t used;
- void *data;
-
- GMutex buffers_map_mutex;
- GHashTable *buffers_map;
-#ifdef GST_WLSINK_ENHANCEMENT
- GMutex displaying_buffers_map_mutex;
- GHashTable *displaying_buffers_map;
-#endif
-};
-
-struct _GstWaylandBufferPoolClass
-{
- GstBufferPoolClass parent_class;
-};
-
-GType gst_wayland_buffer_pool_get_type (void);
-
-GstBufferPool *gst_wayland_buffer_pool_new (GstWlDisplay * display);
-
-
-void gst_wayland_compositor_acquire_buffer (GstWaylandBufferPool * self,
- GstBuffer * buffer);
-void gst_wayland_compositor_release_all_buffers (GstWaylandBufferPool * self);
-void gst_wayland_buffer_pool_add_displaying_buffer (GstBufferPool * pool,
- GstWlMeta * meta, GstBuffer * buffer);
-
-G_END_DECLS
-#endif /*__GST_WAYLAND_BUFFER_POOL_H__*/
+++ /dev/null
-/* GStreamer Wayland video sink
- *
- * Copyright (C) 2014 Collabora Ltd.
- *
- * 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., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301 USA.
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-#include "wldisplay.h"
-#include <errno.h>
-
-#ifdef GST_WLSINK_ENHANCEMENT
-#include <fcntl.h>
-#include <unistd.h>
-#include <xf86drm.h>
-#include <string.h>
-#include <stdlib.h>
-
-static void
-handle_tizen_video_format (void *data, struct tizen_video *tizen_video,
- uint32_t format)
-{
- FUNCTION_ENTER ();
- GstWlDisplay *self = data;
-
- g_return_if_fail (self != NULL);
-
- GST_INFO ("format is %d", format);
- g_array_append_val (self->formats, format);
-}
-
-static const struct tizen_video_listener tz_video_listener = {
- handle_tizen_video_format
-};
-#endif
-
-GST_DEBUG_CATEGORY_EXTERN (gsttizenwl_debug);
-#define GST_CAT_DEFAULT gsttizenwl_debug
-
-G_DEFINE_TYPE (GstWlDisplay, gst_wl_display, G_TYPE_OBJECT);
-
-static void gst_wl_display_finalize (GObject * gobject);
-
-static void
-gst_wl_display_class_init (GstWlDisplayClass * klass)
-{
- FUNCTION_ENTER ();
- GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
- gobject_class->finalize = gst_wl_display_finalize;
-}
-
-static void
-gst_wl_display_init (GstWlDisplay * self)
-{
- FUNCTION_ENTER ();
-
- self->formats = g_array_new (FALSE, FALSE, sizeof (uint32_t));
- self->wl_fd_poll = gst_poll_new (TRUE);
-}
-
-static void
-gst_wl_display_finalize (GObject * gobject)
-{
- FUNCTION_ENTER ();
-
- GstWlDisplay *self = GST_WL_DISPLAY (gobject);
-
- gst_poll_set_flushing (self->wl_fd_poll, TRUE);
-
- if (self->thread)
- g_thread_join (self->thread);
-
-#ifdef GST_WLSINK_ENHANCEMENT
- if (self->is_native_format == FALSE) {
- /*in case of normal video format */
- if (self->tbm_bo)
- tbm_bo_unref (self->tbm_bo);
- self->tbm_bo = NULL;
- }
- if (self->tbm_client) {
- wayland_tbm_client_deinit (self->tbm_client);
- self->tbm_client = NULL;
- }
- self->tbm_bufmgr = NULL;
-#endif
-
- g_array_unref (self->formats);
- gst_poll_free (self->wl_fd_poll);
-
-#ifndef GST_WLSINK_ENHANCEMENT
- if (self->shm)
- wl_shm_destroy (self->shm);
-#endif
-
- if (self->shell)
- wl_shell_destroy (self->shell);
-
- if (self->compositor)
- wl_compositor_destroy (self->compositor);
-
- if (self->subcompositor)
- wl_subcompositor_destroy (self->subcompositor);
-
- if (self->registry)
- wl_registry_destroy (self->registry);
-
- if (self->queue)
- wl_event_queue_destroy (self->queue);
-
- if (self->own_display) {
- wl_display_flush (self->display);
- wl_display_disconnect (self->display);
- }
-#ifdef GST_WLSINK_ENHANCEMENT
- if (self->tizen_policy)
- tizen_policy_destroy (self->tizen_policy);
- if (self->tizen_video)
- tizen_video_destroy (self->tizen_video);
-#endif
-
- G_OBJECT_CLASS (gst_wl_display_parent_class)->finalize (gobject);
-}
-
-static void
-sync_callback (void *data, struct wl_callback *callback, uint32_t serial)
-{
- FUNCTION_ENTER ();
-
- gboolean *done = data;
- *done = TRUE;
-}
-
-static const struct wl_callback_listener sync_listener = {
- sync_callback
-};
-
-static gint
-gst_wl_display_roundtrip (GstWlDisplay * self)
-{
- FUNCTION_ENTER ();
-
- struct wl_callback *callback;
- gint ret = 0;
- gboolean done = FALSE;
-
- g_return_val_if_fail (self != NULL, -1);
-
- /* We don't own the display, process only our queue */
- callback = wl_display_sync (self->display);
- wl_callback_add_listener (callback, &sync_listener, &done);
- wl_proxy_set_queue ((struct wl_proxy *) callback, self->queue);
- while (ret != -1 && !done)
- ret = wl_display_dispatch_queue (self->display, self->queue);
- wl_callback_destroy (callback);
-
- return ret;
-}
-
-static void
-shm_format (void *data, struct wl_shm *wl_shm, uint32_t format)
-{
- FUNCTION_ENTER ();
-
- GstWlDisplay *self = data;
-
- g_array_append_val (self->formats, format);
-}
-
-static const struct wl_shm_listener shm_listener = {
- shm_format
-};
-
-static void
-registry_handle_global (void *data, struct wl_registry *registry,
- uint32_t id, const char *interface, uint32_t version)
-{
-
- FUNCTION_ENTER ();
- GstWlDisplay *self = data;
-
- if (g_strcmp0 (interface, "wl_compositor") == 0) {
- self->compositor = wl_registry_bind (registry, id, &wl_compositor_interface,
- MIN (version, 3));
- } else if (g_strcmp0 (interface, "wl_subcompositor") == 0) {
- self->subcompositor =
- wl_registry_bind (registry, id, &wl_subcompositor_interface, 1);
- } else if (g_strcmp0 (interface, "wl_shell") == 0) {
- self->shell = wl_registry_bind (registry, id, &wl_shell_interface, 1);
-#ifndef GST_WLSINK_ENHANCEMENT
- } else if (g_strcmp0 (interface, "wl_shm") == 0) {
- self->shm = wl_registry_bind (registry, id, &wl_shm_interface, 1);
- wl_shm_add_listener (self->shm, &shm_listener, self);
-#endif
- } else if (g_strcmp0 (interface, "wl_scaler") == 0) {
- self->scaler = wl_registry_bind (registry, id, &wl_scaler_interface, 2);
-#ifdef GST_WLSINK_ENHANCEMENT
- } else if (g_strcmp0 (interface, "tizen_policy") == 0) {
- self->tizen_policy =
- wl_registry_bind (registry, id, &tizen_policy_interface, 1);
- } else if (g_strcmp0 (interface, "tizen_video") == 0) {
- self->tizen_video =
- wl_registry_bind (registry, id, &tizen_video_interface, version);
- g_return_if_fail (self->tizen_video != NULL);
-
- GST_INFO ("id(%d)", id);
-
- tizen_video_add_listener (self->tizen_video, &tz_video_listener, self);
- }
-#endif
-}
-
-static const struct wl_registry_listener registry_listener = {
- registry_handle_global
-};
-
-static gpointer
-gst_wl_display_thread_run (gpointer data)
-{
- FUNCTION_ENTER ();
-
- GstWlDisplay *self = data;
- GstPollFD pollfd = GST_POLL_FD_INIT;
-
- pollfd.fd = wl_display_get_fd (self->display);
- gst_poll_add_fd (self->wl_fd_poll, &pollfd);
- gst_poll_fd_ctl_read (self->wl_fd_poll, &pollfd, TRUE);
-
- /* main loop */
- while (1) {
- while (wl_display_prepare_read_queue (self->display, self->queue) != 0)
- wl_display_dispatch_queue_pending (self->display, self->queue);
- wl_display_flush (self->display);
-
- if (gst_poll_wait (self->wl_fd_poll, GST_CLOCK_TIME_NONE) < 0) {
- gboolean normal = (errno == EBUSY);
- wl_display_cancel_read (self->display);
- if (normal)
- break;
- else
- goto error;
- } else {
- wl_display_read_events (self->display);
- wl_display_dispatch_queue_pending (self->display, self->queue);
- }
- }
-
- return NULL;
-
-error:
- GST_ERROR ("Error communicating with the wayland server");
- return NULL;
-}
-
-GstWlDisplay *
-gst_wl_display_new (const gchar * name, GError ** error)
-{
- FUNCTION_ENTER ();
-
- struct wl_display *display;
-
- display = wl_display_connect (name);
-
- if (!display) {
- *error = g_error_new (g_quark_from_static_string ("GstWlDisplay"), 0,
- "Failed to connect to the wayland display '%s'",
- name ? name : "(default)");
- return NULL;
- } else {
- return gst_wl_display_new_existing (display, TRUE, error);
- }
-}
-
-GstWlDisplay *
-gst_wl_display_new_existing (struct wl_display * display,
- gboolean take_ownership, GError ** error)
-{
- FUNCTION_ENTER ();
-
- GstWlDisplay *self;
- GError *err = NULL;
- gint i;
-
- g_return_val_if_fail (display != NULL, NULL);
-
- self = g_object_new (GST_TYPE_WL_DISPLAY, NULL);
- self->display = display;
- self->own_display = take_ownership;
-
- self->queue = wl_display_create_queue (self->display);
- self->registry = wl_display_get_registry (self->display);
- wl_proxy_set_queue ((struct wl_proxy *) self->registry, self->queue);
- wl_registry_add_listener (self->registry, ®istry_listener, self);
-
- /* we need exactly 2 roundtrips to discover global objects and their state */
- for (i = 0; i < 2; i++) {
- if (gst_wl_display_roundtrip (self) < 0) {
- *error = g_error_new (g_quark_from_static_string ("GstWlDisplay"), 0,
- "Error communicating with the wayland display");
- g_object_unref (self);
- return NULL;
- }
- }
-
- /* verify we got all the required interfaces */
-#define VERIFY_INTERFACE_EXISTS(var, interface) \
- if (!self->var) { \
- g_set_error (error, g_quark_from_static_string ("GstWlDisplay"), 0, \
- "Could not bind to " interface ". Either it is not implemented in " \
- "the compositor, or the implemented version doesn't match"); \
- g_object_unref (self); \
- return NULL; \
- }
-
- VERIFY_INTERFACE_EXISTS (compositor, "wl_compositor");
- VERIFY_INTERFACE_EXISTS (subcompositor, "wl_subcompositor");
- VERIFY_INTERFACE_EXISTS (shell, "wl_shell");
-#ifdef GST_WLSINK_ENHANCEMENT
- VERIFY_INTERFACE_EXISTS (tizen_video, "tizen_video");
- self->tbm_client = wayland_tbm_client_init (self->display);
- if (!self->tbm_client) {
- *error = g_error_new (g_quark_from_static_string ("GstWlDisplay"), 0,
- "Error initializing wayland-tbm");
- g_object_unref (self);
- return NULL;
- }
-#else
- VERIFY_INTERFACE_EXISTS (shm, "wl_shm");
-#endif
- VERIFY_INTERFACE_EXISTS (scaler, "wl_scaler");
-
-#undef VERIFY_INTERFACE_EXISTS
-
- self->thread = g_thread_try_new ("GstWlDisplay", gst_wl_display_thread_run,
- self, &err);
- if (err) {
- g_propagate_prefixed_error (error, err,
- "Failed to start thread for the display's events");
- g_object_unref (self);
- return NULL;
- }
-
- return self;
-}
+++ /dev/null
-/* GStreamer Wayland video sink
- *
- * Copyright (C) 2014 Collabora Ltd.
- *
- * 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., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301 USA.
- */
-
-#ifndef __GST_WL_DISPLAY_H__
-#define __GST_WL_DISPLAY_H__
-
-#include <gst/gst.h>
-#include <wayland-client.h>
-#include "scaler-client-protocol.h"
-#ifdef GST_WLSINK_ENHANCEMENT
-#include <tbm_bufmgr.h>
-#include <wayland-tbm-client.h>
-#include <tizen-extension-client-protocol.h>
-#define NV_BUF_PLANE_NUM 2 /*SN12 or ST12 has 2 plane */
-#endif
-G_BEGIN_DECLS
-#define GST_TYPE_WL_DISPLAY (gst_wl_display_get_type ())
-#define GST_WL_DISPLAY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_WL_DISPLAY, GstWlDisplay))
-#define GST_IS_WL_DISPLAY(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_WL_DISPLAY))
-#define GST_WL_DISPLAY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_WL_DISPLAY, GstWlDisplayClass))
-#define GST_IS_WL_DISPLAY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_WL_DISPLAY))
-#define GST_WL_DISPLAY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_WL_DISPLAY, GstWlDisplayClass))
-#if 1
-#define FUNCTION_ENTER() GST_INFO("<ENTER>")
-#else
-#define FUNCTION_ENTER()
-#endif
-typedef struct _GstWlDisplay GstWlDisplay;
-typedef struct _GstWlDisplayClass GstWlDisplayClass;
-
-struct _GstWlDisplay
-{
- GObject parent_instance;
-
- /* public objects */
- struct wl_display *display;
- struct wl_event_queue *queue;
-
- /* globals */
- struct wl_registry *registry;
- struct wl_compositor *compositor;
- struct wl_subcompositor *subcompositor;
- struct wl_shell *shell;
- struct wl_shm *shm;
- struct wl_scaler *scaler;
- GArray *formats;
-
- /* private */
- gboolean own_display;
- GThread *thread;
- GstPoll *wl_fd_poll;
-
-#ifdef GST_WLSINK_ENHANCEMENT
- /*video output layer */
- struct tizen_policy *tizen_policy;
- struct tizen_video *tizen_video;
-
- struct wayland_tbm_client *tbm_client;
- tbm_bufmgr tbm_bufmgr;
- tbm_bo tbm_bo;
-
- int need_shell_surface;
-
- gboolean is_native_format; /*SN12, ST12 */
- void *bo[NV_BUF_PLANE_NUM];
- int plane_size[NV_BUF_PLANE_NUM];
- int stride_width[NV_BUF_PLANE_NUM];
- int stride_height[NV_BUF_PLANE_NUM];
- int native_video_size;
-#endif
-};
-
-struct _GstWlDisplayClass
-{
- GObjectClass parent_class;
-};
-
-GType gst_wl_display_get_type (void);
-
-GstWlDisplay *gst_wl_display_new (const gchar * name, GError ** error);
-GstWlDisplay *gst_wl_display_new_existing (struct wl_display *display,
- gboolean take_ownership, GError ** error);
-
-G_END_DECLS
-#endif /* __GST_WL_DISPLAY_H__ */
+++ /dev/null
-/* GStreamer Wayland video sink
- *
- * Copyright (C) 2011 Intel Corporation
- * Copyright (C) 2011 Sreerenj Balachandran <sreerenj.balachandran@intel.com>
- * Copyright (C) 2012 Wim Taymans <wim.taymans@gmail.com>
- * Copyright (C) 2014 Collabora Ltd.
- *
- * 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., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301 USA.
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include "wlvideoformat.h"
-
-GST_DEBUG_CATEGORY_EXTERN (gsttizenwl_debug);
-#define GST_CAT_DEFAULT gsttizenwl_debug
-
-#ifndef GST_WLSINK_ENHANCEMENT
-
-typedef struct
-{
- enum wl_shm_format wl_format;
- GstVideoFormat gst_format;
-} wl_VideoFormat;
-
-static const wl_VideoFormat formats[] = {
-#if G_BYTE_ORDER == G_BIG_ENDIAN
- {WL_SHM_FORMAT_XRGB8888, GST_VIDEO_FORMAT_xRGB},
- {WL_SHM_FORMAT_ARGB8888, GST_VIDEO_FORMAT_ARGB},
- {WL_SHM_FORMAT_XBGR8888, GST_VIDEO_FORMAT_xBGR},
- {WL_SHM_FORMAT_RGBX8888, GST_VIDEO_FORMAT_RGBx},
- {WL_SHM_FORMAT_BGRX8888, GST_VIDEO_FORMAT_BGRx},
- {WL_SHM_FORMAT_ABGR8888, GST_VIDEO_FORMAT_ABGR},
- {WL_SHM_FORMAT_RGBA8888, GST_VIDEO_FORMAT_RGBA},
- {WL_SHM_FORMAT_BGRA8888, GST_VIDEO_FORMAT_BGRA},
-#else
- {WL_SHM_FORMAT_XRGB8888, GST_VIDEO_FORMAT_BGRx},
- {WL_SHM_FORMAT_ARGB8888, GST_VIDEO_FORMAT_BGRA},
- {WL_SHM_FORMAT_XBGR8888, GST_VIDEO_FORMAT_RGBx},
- {WL_SHM_FORMAT_RGBX8888, GST_VIDEO_FORMAT_xBGR},
- {WL_SHM_FORMAT_BGRX8888, GST_VIDEO_FORMAT_xRGB},
- {WL_SHM_FORMAT_ABGR8888, GST_VIDEO_FORMAT_RGBA},
- {WL_SHM_FORMAT_RGBA8888, GST_VIDEO_FORMAT_ABGR},
- {WL_SHM_FORMAT_BGRA8888, GST_VIDEO_FORMAT_ARGB},
-#endif
- {WL_SHM_FORMAT_RGB888, GST_VIDEO_FORMAT_RGB},
- {WL_SHM_FORMAT_BGR888, GST_VIDEO_FORMAT_BGR},
- {WL_SHM_FORMAT_RGB565, GST_VIDEO_FORMAT_RGB16},
- {WL_SHM_FORMAT_BGR565, GST_VIDEO_FORMAT_BGR16},
-
- {WL_SHM_FORMAT_YUYV, GST_VIDEO_FORMAT_YUY2},
- {WL_SHM_FORMAT_YVYU, GST_VIDEO_FORMAT_YVYU},
- {WL_SHM_FORMAT_UYVY, GST_VIDEO_FORMAT_UYVY},
- {WL_SHM_FORMAT_AYUV, GST_VIDEO_FORMAT_AYUV},
- {WL_SHM_FORMAT_NV12, GST_VIDEO_FORMAT_NV12},
- {WL_SHM_FORMAT_NV21, GST_VIDEO_FORMAT_NV21},
- {WL_SHM_FORMAT_NV16, GST_VIDEO_FORMAT_NV16},
- {WL_SHM_FORMAT_YUV410, GST_VIDEO_FORMAT_YUV9},
- {WL_SHM_FORMAT_YVU410, GST_VIDEO_FORMAT_YVU9},
- {WL_SHM_FORMAT_YUV411, GST_VIDEO_FORMAT_Y41B},
- {WL_SHM_FORMAT_YUV420, GST_VIDEO_FORMAT_I420},
- {WL_SHM_FORMAT_YVU420, GST_VIDEO_FORMAT_YV12},
- {WL_SHM_FORMAT_YUV422, GST_VIDEO_FORMAT_Y42B},
- {WL_SHM_FORMAT_YUV444, GST_VIDEO_FORMAT_v308},
-};
-
-enum wl_shm_format
-gst_video_format_to_wayland_format (GstVideoFormat format)
-{
- guint i;
-
- for (i = 0; i < G_N_ELEMENTS (formats); i++)
- if (formats[i].gst_format == format)
- return formats[i].wl_format;
-
- GST_WARNING ("wayland video format not found");
- return -1;
-}
-
-GstVideoFormat
-gst_wayland_format_to_video_format (enum wl_shm_format wl_format)
-{
- guint i;
-
- for (i = 0; i < G_N_ELEMENTS (formats); i++)
- if (formats[i].wl_format == wl_format)
- return formats[i].gst_format;
-
- GST_WARNING ("gst video format not found");
- return GST_VIDEO_FORMAT_UNKNOWN;
-}
-
-const gchar *
-gst_wayland_format_to_string (enum wl_shm_format wl_format)
-{
- return gst_video_format_to_string
- (gst_wayland_format_to_video_format (wl_format));
-}
-#endif
+++ /dev/null
-/* GStreamer Wayland video sink
- *
- * Copyright (C) 2011 Intel Corporation
- * Copyright (C) 2011 Sreerenj Balachandran <sreerenj.balachandran@intel.com>
- * Copyright (C) 2012 Wim Taymans <wim.taymans@gmail.com>
- * Copyright (C) 2014 Collabora Ltd.
- *
- * 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., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301 USA.
- */
-
-#ifndef __GST_WL_VIDEO_FORMAT_H__
-#define __GST_WL_VIDEO_FORMAT_H__
-
-#include <wayland-client.h>
-#include <gst/video/video.h>
-
-#ifndef GST_WLSINK_ENHANCEMENT
-
-G_BEGIN_DECLS
- enum wl_shm_format gst_video_format_to_wayland_format (GstVideoFormat
- format);
-GstVideoFormat gst_wayland_format_to_video_format (enum wl_shm_format
- wl_format);
-
-const gchar *gst_wayland_format_to_string (enum wl_shm_format wl_format);
-
-G_END_DECLS
-#endif
-#endif
+++ /dev/null
-/* GStreamer Wayland video sink
- *
- * Copyright (C) 2011 Intel Corporation
- * Copyright (C) 2011 Sreerenj Balachandran <sreerenj.balachandran@intel.com>
- * Copyright (C) 2014 Collabora Ltd.
- *
- * 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., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301 USA.
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include "wlwindow.h"
-#ifdef GST_WLSINK_ENHANCEMENT
-#include "gstwaylandsink.h"
-#define SWAP(a, b) { (a) ^= (b) ^= (a) ^= (b); }
-#endif
-
-GST_DEBUG_CATEGORY_EXTERN (gsttizenwl_debug);
-#define GST_CAT_DEFAULT gsttizenwl_debug
-
-G_DEFINE_TYPE (GstWlWindow, gst_wl_window, G_TYPE_OBJECT);
-
-static void gst_wl_window_finalize (GObject * gobject);
-
-static void
-handle_ping (void *data, struct wl_shell_surface *shell_surface,
- uint32_t serial)
-{
- FUNCTION_ENTER ();
-
- wl_shell_surface_pong (shell_surface, serial);
-}
-
-static void
-handle_configure (void *data, struct wl_shell_surface *shell_surface,
- uint32_t edges, int32_t width, int32_t height)
-{
- FUNCTION_ENTER ();
-
-}
-
-static void
-handle_popup_done (void *data, struct wl_shell_surface *shell_surface)
-{
- FUNCTION_ENTER ();
-
-}
-
-static const struct wl_shell_surface_listener shell_surface_listener = {
- handle_ping,
- handle_configure,
- handle_popup_done
-};
-
-static void
-gst_wl_window_class_init (GstWlWindowClass * klass)
-{
- FUNCTION_ENTER ();
-
- GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
- gobject_class->finalize = gst_wl_window_finalize;
-}
-
-static void
-gst_wl_window_init (GstWlWindow * self)
-{
- FUNCTION_ENTER ();
-
-}
-
-static void
-gst_wl_window_finalize (GObject * gobject)
-{
- FUNCTION_ENTER ();
-
- GstWlWindow *self = GST_WL_WINDOW (gobject);
-
-#ifdef GST_WLSINK_ENHANCEMENT
- tizen_video_object_destroy (self->video_object);
-#endif
-
- if (self->shell_surface) {
- wl_shell_surface_destroy (self->shell_surface);
- }
-
- if (self->subsurface) {
- wl_subsurface_destroy (self->subsurface);
- }
-
- wl_viewport_destroy (self->viewport);
- wl_surface_destroy (self->surface);
-
- g_clear_object (&self->display);
-
- G_OBJECT_CLASS (gst_wl_window_parent_class)->finalize (gobject);
-}
-
-static GstWlWindow *
-gst_wl_window_new_internal (GstWlDisplay * display, struct wl_surface *surface)
-{
- FUNCTION_ENTER ();
-
- GstWlWindow *window;
- struct wl_region *region;
-
- g_return_val_if_fail (surface != NULL, NULL);
-
- window = g_object_new (GST_TYPE_WL_WINDOW, NULL);
- window->display = g_object_ref (display);
- window->surface = surface;
-
- /* make sure the surface runs on our local queue */
- wl_proxy_set_queue ((struct wl_proxy *) surface, display->queue);
-
-#ifdef GST_WLSINK_ENHANCEMENT
- /* create shell_surface here for enlightenment */
- if (display->need_shell_surface)
- window->shell_surface = wl_shell_get_shell_surface (display->shell,
- window->surface);
-#endif
-
- window->viewport = wl_scaler_get_viewport (display->scaler, window->surface);
-
- /* do not accept input */
- region = wl_compositor_create_region (display->compositor);
- wl_surface_set_input_region (surface, region);
- wl_region_destroy (region);
-
-#ifdef GST_WLSINK_ENHANCEMENT
- window->video_object =
- tizen_video_get_object (display->tizen_video, window->surface);
-#endif
-
- return window;
-}
-
-GstWlWindow *
-gst_wl_window_new_toplevel (GstWlDisplay * display, GstVideoInfo * video_info)
-{
- FUNCTION_ENTER ();
-
- GstWlWindow *window;
-
- /* not create shell_surface here for enlightenment */
- display->need_shell_surface = TRUE;
-
- window = gst_wl_window_new_internal (display,
- wl_compositor_create_surface (display->compositor));
-
- gst_wl_window_set_video_info (window, video_info);
- gst_wl_window_set_render_rectangle (window, 0, 0, window->video_width,
- window->video_height);
-
-#ifndef GST_WLSINK_ENHANCEMENT
- /* go toplevel */
- window->shell_surface = wl_shell_get_shell_surface (display->shell,
- window->area_surface);
-#endif
-
- if (window->shell_surface) {
- wl_shell_surface_add_listener (window->shell_surface,
- &shell_surface_listener, window);
- wl_shell_surface_set_toplevel (window->shell_surface);
- } else {
- GST_ERROR ("Unable to get wl_shell_surface");
-
- g_object_unref (window);
- return NULL;
- }
-
- return window;
-}
-
-GstWlWindow *
-gst_wl_window_new_in_surface (GstWlDisplay * display,
- struct wl_surface * parent)
-{
- FUNCTION_ENTER ();
-
- GstWlWindow *window;
-
- window = gst_wl_window_new_internal (display,
- wl_compositor_create_surface (display->compositor));
-
- window->subsurface = wl_subcompositor_get_subsurface (display->subcompositor,
- window->surface, parent);
- wl_subsurface_set_desync (window->subsurface);
-#ifdef GST_WLSINK_ENHANCEMENT
- if (display->tizen_policy)
- tizen_policy_place_subsurface_below_parent (display->tizen_policy,
- window->subsurface);
-
- wl_surface_commit (parent);
-#endif
- return window;
-}
-
-GstWlDisplay *
-gst_wl_window_get_display (GstWlWindow * window)
-{
- FUNCTION_ENTER ();
-
- g_return_val_if_fail (window != NULL, NULL);
-
- return g_object_ref (window->display);
-}
-
-struct wl_surface *
-gst_wl_window_get_wl_surface (GstWlWindow * window)
-{
- FUNCTION_ENTER ();
-
- g_return_val_if_fail (window != NULL, NULL);
-
- return window->surface;
-}
-
-gboolean
-gst_wl_window_is_toplevel (GstWlWindow * window)
-{
- FUNCTION_ENTER ();
-
- g_return_val_if_fail (window != NULL, FALSE);
-
- return (window->shell_surface != NULL);
-}
-
-static void
-gst_wl_window_resize_internal (GstWlWindow * window, gboolean commit)
-{
- FUNCTION_ENTER ();
-
- GstVideoRectangle src = { 0, };
- GstVideoRectangle res; //dst
-
- src.w = window->video_width;
- src.h = window->video_height;
-#ifdef GST_WLSINK_ENHANCEMENT // need to change ifndef to ifdef
-
- GstVideoRectangle src_origin = { 0, 0, 0, 0 };
- GstVideoRectangle src_input = { 0, 0, 0, 0 };
- GstVideoRectangle dst = { 0, 0, 0, 0 };
-
- gint rotate = 0;
- gint transform = WL_OUTPUT_TRANSFORM_NORMAL;
-
- src.x = src.y = 0;
- src_input.w = src_origin.w = window->video_width;
- src_input.h = src_origin.h = window->video_height;
- GST_INFO ("video (%d x %d)", window->video_width, window->video_height);
- GST_INFO ("src_input(%d, %d, %d x %d)", src_input.x, src_input.y, src_input.w,
- src_input.h);
- GST_INFO ("src_origin(%d, %d, %d x %d)", src_origin.x, src_origin.y,
- src_origin.w, src_origin.h);
-
- if (window->rotate_angle == DEGREE_0 || window->rotate_angle == DEGREE_180) {
- src.w = window->video_width; //video_width
- src.h = window->video_height; //video_height
- } else {
- src.w = window->video_height;
- src.h = window->video_width;
- }
- GST_INFO ("src(%d, %d, %d x %d)", src.x, src.y, src.w, src.h);
-
- /*default res.w and res.h */
- dst.w = window->render_rectangle.w;
- dst.h = window->render_rectangle.h;
- GST_INFO ("dst(%d,%d,%d x %d)", dst.x, dst.y, dst.w, dst.h);
- GST_INFO ("window->render_rectangle(%d,%d,%d x %d)",
- window->render_rectangle.x, window->render_rectangle.y,
- window->render_rectangle.w, window->render_rectangle.h);
- switch (window->disp_geo_method) {
- case DISP_GEO_METHOD_LETTER_BOX:
- GST_INFO ("DISP_GEO_METHOD_LETTER_BOX");
- gst_video_sink_center_rect (src, dst, &res, TRUE);
- gst_video_sink_center_rect (dst, src, &src_input, FALSE);
- res.x += window->render_rectangle.x;
- res.y += window->render_rectangle.y;
- break;
- case DISP_GEO_METHOD_ORIGIN_SIZE_OR_LETTER_BOX:
- if (src.w > dst.w || src.h > dst.h) {
- /*LETTER BOX */
- GST_INFO
- ("DISP_GEO_METHOD_ORIGIN_SIZE_OR_LETTER_BOX -> set LETTER BOX");
- gst_video_sink_center_rect (src, dst, &res, TRUE);
- gst_video_sink_center_rect (dst, src, &src_input, FALSE);
- res.x += window->render_rectangle.x;
- res.y += window->render_rectangle.y;
- } else {
- /*ORIGIN SIZE */
- GST_INFO ("DISP_GEO_METHOD_ORIGIN_SIZE");
- gst_video_sink_center_rect (src, dst, &res, FALSE);
- gst_video_sink_center_rect (dst, src, &src_input, FALSE);
- }
- break;
- case DISP_GEO_METHOD_ORIGIN_SIZE: //is working
- GST_INFO ("DISP_GEO_METHOD_ORIGIN_SIZE");
- gst_video_sink_center_rect (src, dst, &res, FALSE);
- gst_video_sink_center_rect (dst, src, &src_input, FALSE);
- break;
- case DISP_GEO_METHOD_FULL_SCREEN: //is working
- GST_INFO ("DISP_GEO_METHOD_FULL_SCREEN");
- res.x = res.y = 0;
- res.w = window->render_rectangle.w;
- res.h = window->render_rectangle.h;
- break;
- case DISP_GEO_METHOD_CROPPED_FULL_SCREEN:
- GST_INFO ("DISP_GEO_METHOD_CROPPED_FULL_SCREEN");
- gst_video_sink_center_rect (src, dst, &res, FALSE);
- gst_video_sink_center_rect (dst, src, &src_input, FALSE);
- res.x = res.y = 0;
- res.w = dst.w;
- res.h = dst.h;
- break;
- default:
- break;
- }
-
- switch (window->rotate_angle) {
- case DEGREE_0:
- transform = WL_OUTPUT_TRANSFORM_NORMAL;
- break;
- case DEGREE_90:
- transform = WL_OUTPUT_TRANSFORM_90;
- break;
- case DEGREE_180:
- transform = WL_OUTPUT_TRANSFORM_180;
- break;
- case DEGREE_270:
- transform = WL_OUTPUT_TRANSFORM_270;
- break;
-
- default:
- GST_ERROR ("Unsupported rotation [%d]... set DEGREE 0.",
- window->rotate_angle);
- break;
- }
-
- switch (window->flip) {
- case FLIP_NONE:
- break;
- case FLIP_VERTICAL:
- transform = WL_OUTPUT_TRANSFORM_FLIPPED;
- break;
- case FLIP_HORIZONTAL:
- transform = WL_OUTPUT_TRANSFORM_FLIPPED_180;
- break;
- case FLIP_BOTH:
- transform = WL_OUTPUT_TRANSFORM_180;
- break;
- default:
- GST_ERROR ("Unsupported flip [%d]... set FLIP_NONE.", window->flip);
- }
-
- GST_INFO
- ("window[%d x %d] src[%d,%d,%d x %d],dst[%d,%d,%d x %d],input[%d,%d,%d x %d],result[%d,%d,%d x %d]",
- window->render_rectangle.w, window->render_rectangle.h,
- src.x, src.y, src.w, src.h,
- dst.x, dst.y, dst.w, dst.h,
- src_input.x, src_input.y, src_input.w, src_input.h,
- res.x, res.y, res.w, res.h);
-
- GST_INFO ("video (%d x %d)", window->video_width, window->video_height);
- GST_INFO ("src_input(%d, %d, %d x %d)", src_input.x, src_input.y, src_input.w,
- src_input.h);
- GST_INFO ("src_origin(%d, %d, %d x %d)", src_origin.x, src_origin.y,
- src_origin.w, src_origin.h);
- GST_INFO ("src(%d, %d, %d x %d)", src.x, src.y, src.w, src.h);
- GST_INFO ("dst(%d,%d,%d x %d)", dst.x, dst.y, dst.w, dst.h);
- GST_INFO ("window->render_rectangle(%d,%d,%d x %d)",
- window->render_rectangle.x, window->render_rectangle.y,
- window->render_rectangle.w, window->render_rectangle.h);
- GST_INFO ("res(%d, %d, %d x %d)", res.x, res.y, res.w, res.h);
-
- if (window->subsurface) {
- GST_INFO ("have window->subsurface");
- wl_subsurface_set_position (window->subsurface,
- window->render_rectangle.x + res.x, window->render_rectangle.y + res.y);
- GST_INFO ("wl_subsurface_set_position(%d,%d)",
- window->render_rectangle.x + res.x, window->render_rectangle.y + res.y);
- }
- wl_viewport_set_destination (window->viewport, res.w, res.h);
- GST_INFO ("wl_viewport_set_destination(%d,%d)", res.w, res.h);
-
- wl_viewport_set_source (window->viewport, wl_fixed_from_int (src_input.x),
- wl_fixed_from_int (src_input.y), wl_fixed_from_int (src_input.w),
- wl_fixed_from_int (src_input.h));
- GST_INFO ("wl_viewport_set_source(%d,%d, %d x %d)", src_input.x, src_input.y,
- src_input.w, src_input.h);
-
- wl_surface_set_buffer_transform (window->surface, transform);
- GST_INFO ("wl_surface_set_buffer_transform (%d)", transform);
-
- if (commit) {
- wl_surface_damage (window->surface, 0, 0, res.w, res.h);
- wl_surface_commit (window->surface);
- }
-
- /* this is saved for use in wl_surface_damage */
- window->surface_width = res.w;
- window->surface_height = res.h;
-
-#else
- gst_video_sink_center_rect (src, window->render_rectangle, &res, TRUE);
- if (window->subsurface)
- wl_subsurface_set_position (window->subsurface,
- window->render_rectangle.x + res.x, window->render_rectangle.y + res.y);
-
- wl_viewport_set_destination (window->viewport, res.w, res.h);
-
- if (commit) {
- wl_surface_damage (window->surface, 0, 0, res.w, res.h);
- wl_surface_commit (window->surface);
- }
-
- /* this is saved for use in wl_surface_damage */
- window->surface_width = res.w;
- window->surface_height = res.h;
-#endif
-}
-
-void
-gst_wl_window_set_video_info (GstWlWindow * window, GstVideoInfo * info)
-{
- FUNCTION_ENTER ();
-
- g_return_if_fail (window != NULL);
-
- window->video_width =
- gst_util_uint64_scale_int_round (info->width, info->par_n, info->par_d);
- window->video_height = info->height;
-
- if (window->render_rectangle.w != 0)
- gst_wl_window_resize_internal (window, FALSE);
-}
-
-void
-gst_wl_window_set_render_rectangle (GstWlWindow * window, gint x, gint y,
- gint w, gint h)
-{
- FUNCTION_ENTER ();
-
- g_return_if_fail (window != NULL);
-
- window->render_rectangle.x = x;
- window->render_rectangle.y = y;
- window->render_rectangle.w = w;
- window->render_rectangle.h = h;
-
- if (window->video_width != 0)
- gst_wl_window_resize_internal (window, TRUE);
-}
-
-#ifdef GST_WLSINK_ENHANCEMENT
-void
-gst_wl_window_set_rotate_angle (GstWlWindow * window, guint rotate_angle)
-{
- FUNCTION_ENTER ();
- g_return_if_fail (window != NULL);
- window->rotate_angle = rotate_angle;
- GST_INFO ("rotate_angle value is (%d)", window->rotate_angle);
-
-}
-
-void
-gst_wl_window_set_disp_geo_method (GstWlWindow * window, guint disp_geo_method)
-{
- FUNCTION_ENTER ();
- g_return_if_fail (window != NULL);
- window->disp_geo_method = disp_geo_method;
- GST_INFO ("disp_geo_method value is (%d)", window->disp_geo_method);
-}
-
-void
-gst_wl_window_set_orientation (GstWlWindow * window, guint orientation)
-{
- FUNCTION_ENTER ();
- g_return_if_fail (window != NULL);
- window->orientation = orientation;
- GST_INFO ("orientation value is (%d)", window->orientation);
-}
-
-void
-gst_wl_window_set_flip (GstWlWindow * window, guint flip)
-{
- FUNCTION_ENTER ();
- g_return_if_fail (window != NULL);
- window->flip = flip;
- GST_INFO ("flip value is (%d)", window->flip);
-}
-#endif
+++ /dev/null
-/* GStreamer Wayland video sink
- *
- * Copyright (C) 2014 Collabora Ltd.
- *
- * 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., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301 USA.
- */
-
-#ifndef __GST_WL_WINDOW_H__
-#define __GST_WL_WINDOW_H__
-
-#include "wldisplay.h"
-#include <gst/video/video.h>
-
-G_BEGIN_DECLS
-#define GST_TYPE_WL_WINDOW (gst_wl_window_get_type ())
-#define GST_WL_WINDOW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_WL_WINDOW, GstWlWindow))
-#define GST_IS_WL_WINDOW(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_WL_WINDOW))
-#define GST_WL_WINDOW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_WL_WINDOW, GstWlWindowClass))
-#define GST_IS_WL_WINDOW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_WL_WINDOW))
-#define GST_WL_WINDOW_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_WL_WINDOW, GstWlWindowClass))
-#if 1
-#define FUNCTION_ENTER() GST_INFO("<ENTER>")
-#else
-#define FUNCTION_ENTER()
-#endif
-typedef struct _GstWlWindow GstWlWindow;
-typedef struct _GstWlWindowClass GstWlWindowClass;
-
-struct _GstWlWindow
-{
- GObject parent_instance;
-
- GstWlDisplay *display;
- struct wl_surface *surface;
- struct wl_subsurface *subsurface;
- struct wl_viewport *viewport;
- struct wl_shell_surface *shell_surface;
-
- /* the size of the destination area where we are overlaying our subsurface */
- GstVideoRectangle render_rectangle;
- /* the size of the video in the buffers */
- gint video_width, video_height;
- /* the size of the (sub)surface */
- gint surface_width, surface_height;
-#ifdef GST_WLSINK_ENHANCEMENT
- struct tizen_video_object *video_object;
-
- /*Display geometry method */
- guint disp_geo_method;
- guint rotate_angle;
- guint orientation;
- guint flip;
-#endif
-};
-
-struct _GstWlWindowClass
-{
- GObjectClass parent_class;
-};
-
-GType gst_wl_window_get_type (void);
-
-GstWlWindow *gst_wl_window_new_toplevel (GstWlDisplay * display,
- GstVideoInfo * video_info);
-GstWlWindow *gst_wl_window_new_in_surface (GstWlDisplay * display,
- struct wl_surface *parent);
-
-GstWlDisplay *gst_wl_window_get_display (GstWlWindow * window);
-struct wl_surface *gst_wl_window_get_wl_surface (GstWlWindow * window);
-gboolean gst_wl_window_is_toplevel (GstWlWindow * window);
-
-/* functions to manipulate the size on non-toplevel windows */
-void gst_wl_window_set_video_info (GstWlWindow * window, GstVideoInfo * info);
-void gst_wl_window_set_render_rectangle (GstWlWindow * window, gint x, gint y,
- gint w, gint h);
-
-#ifdef GST_WLSINK_ENHANCEMENT
-void gst_wl_window_set_rotate_angle (GstWlWindow * window, guint rotate_angle);
-void gst_wl_window_set_disp_geo_method (GstWlWindow * window,
- guint disp_geo_method);
-void gst_wl_window_set_orientation (GstWlWindow * window, guint orientation);
-void gst_wl_window_set_flip (GstWlWindow * window, guint flip);
-#endif
-
-
-G_END_DECLS
-#endif /* __GST_WL_WINDOW_H__ */