From 33dad088465f45a2139fb99c3aa254956eecf9e6 Mon Sep 17 00:00:00 2001 From: NAMJEONGYOON Date: Wed, 20 Jul 2016 14:01:02 +0900 Subject: [PATCH] remove unused plugins Change-Id: I7d562043a9220bca09dd20894a03685fb7354675 --- Makefile.am | 12 - configure.ac | 130 +- evaspixmapsink/Makefile.am | 14 - evaspixmapsink/evaspixmapsink.c | 3755 --------------------------------- evaspixmapsink/evaspixmapsink.h | 388 ---- evaspixmapsink/xv_types.h | 41 - packaging/gst-plugins-tizen.spec | 1 - waylandsink/Makefile.am | 1 - waylandsink/src/Makefile.am | 46 - waylandsink/src/gstwaylandsink.c | 1371 ------------ waylandsink/src/gstwaylandsink.h | 126 -- waylandsink/src/scaler.xml | 210 -- waylandsink/src/tizen-wlvideoformat.c | 113 - waylandsink/src/tizen-wlvideoformat.h | 41 - waylandsink/src/waylandpool.c | 769 ------- waylandsink/src/waylandpool.h | 111 - waylandsink/src/wldisplay.c | 358 ---- waylandsink/src/wldisplay.h | 102 - waylandsink/src/wlvideoformat.c | 114 - waylandsink/src/wlvideoformat.h | 42 - waylandsink/src/wlwindow.c | 506 ----- waylandsink/src/wlwindow.h | 100 - 22 files changed, 2 insertions(+), 8349 deletions(-) delete mode 100644 evaspixmapsink/Makefile.am delete mode 100755 evaspixmapsink/evaspixmapsink.c delete mode 100755 evaspixmapsink/evaspixmapsink.h delete mode 100644 evaspixmapsink/xv_types.h delete mode 100644 waylandsink/Makefile.am delete mode 100644 waylandsink/src/Makefile.am delete mode 100644 waylandsink/src/gstwaylandsink.c delete mode 100644 waylandsink/src/gstwaylandsink.h delete mode 100644 waylandsink/src/scaler.xml delete mode 100644 waylandsink/src/tizen-wlvideoformat.c delete mode 100644 waylandsink/src/tizen-wlvideoformat.h delete mode 100644 waylandsink/src/waylandpool.c delete mode 100644 waylandsink/src/waylandpool.h delete mode 100644 waylandsink/src/wldisplay.c delete mode 100644 waylandsink/src/wldisplay.h delete mode 100644 waylandsink/src/wlvideoformat.c delete mode 100644 waylandsink/src/wlvideoformat.h delete mode 100644 waylandsink/src/wlwindow.c delete mode 100644 waylandsink/src/wlwindow.h diff --git a/Makefile.am b/Makefile.am index b24db2f..9536e2a 100644 --- a/Makefile.am +++ b/Makefile.am @@ -13,10 +13,6 @@ if GST_TIZEN_USE_EVASIMAGESINK SUBDIRS += evasimagesink endif -#if GST_TIZEN_USE_EVASPIXMAPSINK -#SUBDIRS += evaspixmapsink -#endif - if GST_TIZEN_USE_XVIMAGESRC SUBDIRS += xvimagesrc endif @@ -65,10 +61,6 @@ if GST_TIZEN_USE_TIZENIPC SUBDIRS += tizenipc endif -#if GST_TIZEN_USE_WAYLANDSINK -#SUBDIRS += waylandsink -#endif - DIST_SUBDIRS = common if GST_TIZEN_USE_ENCODEBIN @@ -112,10 +104,6 @@ if GST_TIZEN_USE_DRMDECRYPTOR 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 \ diff --git a/configure.ac b/configure.ac index 8508a31..7e13e49 100644 --- a/configure.ac +++ b/configure.ac @@ -171,7 +171,7 @@ AC_SUBST(TBM_LIBS) 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 @@ -187,7 +187,7 @@ PKG_CHECK_MODULES(EFL, [ ]) ]) -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 @@ -196,97 +196,6 @@ GST_LICENSE="LGPL" AC_DEFINE_UNQUOTED(GST_LICENSE, "$GST_LICENSE", [GStreamer license]) AC_SUBST(GST_LICENSE) -echo -AC_MSG_NOTICE([Checking libraries for evaspixmapsink plugin]) -echo -dnl *** X11 *** -translit(dnm, m, l) AM_CONDITIONAL(USE_X, true) -AG_GST_CHECK_FEATURE(X, [X libraries and plugins], - [evaspixmapsink], [ - AC_PATH_XTRA - ac_cflags_save="$CFLAGS" - ac_cppflags_save="$CPPFLAGS" - CFLAGS="$CFLAGS $X_CFLAGS" - CPPFLAGS="$CPPFLAGS $X_CFLAGS" - - dnl now try to find the HEADER - AC_CHECK_HEADER(X11/Xlib.h, HAVE_X="yes", HAVE_X="no") - - if test "x$HAVE_X" = "xno" - then - AC_MSG_NOTICE([cannot find X11 development files]) - else - dnl this is much more than we want - X_LIBS="$X_LIBS $X_PRE_LIBS $X_EXTRA_LIBS" - dnl AC_PATH_XTRA only defines the path needed to find the X libs, - dnl it does not add the libs; therefore we add them here - X_LIBS="$X_LIBS -lX11" - AC_SUBST(X_CFLAGS) - AC_SUBST(X_LIBS) - - 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) @@ -315,18 +224,6 @@ AC_ARG_ENABLE(evasimagesink, AC_HELP_STRING([--enable-evasimagesink], [using eva [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]), [ @@ -478,26 +375,6 @@ AC_ARG_ENABLE(drmdecryptor, AC_HELP_STRING([--enable-drmdecryptor], [using drmde [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]), [ @@ -520,7 +397,6 @@ encodebin/Makefile encodebin/src/Makefile evasimagesink/Makefile evasimagesink/src/Makefile -evaspixmapsink/Makefile xvimagesrc/Makefile xvimagesrc/src/Makefile toggle/Makefile @@ -540,8 +416,6 @@ waylandsrc/Makefile waylandsrc/src/Makefile drmdecryptor/Makefile drmdecryptor/src/Makefile -waylandsink/Makefile -waylandsink/src/Makefile tizenipc/Makefile tizenipc/src/Makefile ) diff --git a/evaspixmapsink/Makefile.am b/evaspixmapsink/Makefile.am deleted file mode 100644 index d02b8d7..0000000 --- a/evaspixmapsink/Makefile.am +++ /dev/null @@ -1,14 +0,0 @@ -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 diff --git a/evaspixmapsink/evaspixmapsink.c b/evaspixmapsink/evaspixmapsink.c deleted file mode 100755 index 532c123..0000000 --- a/evaspixmapsink/evaspixmapsink.c +++ /dev/null @@ -1,3755 +0,0 @@ -/* - * EvasPixmapSink - * - * Copyright (c) 2000 - 2012 Samsung Electronics Co., Ltd. All rights reserved. - * - * Contact: Sangchul Lee - * - * 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 -#include -//#include -#include -/* Helper functions */ -#include - -/* 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 -#include -#include -#include -#include -#include -#include - -//#define DUMP_IMG -#ifdef DUMP_IMG -#include -#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_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 "); - - 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) diff --git a/evaspixmapsink/evaspixmapsink.h b/evaspixmapsink/evaspixmapsink.h deleted file mode 100755 index 22ca115..0000000 --- a/evaspixmapsink/evaspixmapsink.h +++ /dev/null @@ -1,388 +0,0 @@ -/* - * EvasPixmapSink - * - * Copyright (c) 2000 - 2012 Samsung Electronics Co., Ltd. All rights reserved. - * - * Contact: Sangchul Lee - * - * 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 - -#ifdef HAVE_XSHM -#include -#include -#include -#endif /* HAVE_XSHM */ - -#include -#include - -#ifdef HAVE_XSHM -#include -#endif /* HAVE_XSHM */ - -#include -#include -#include -#include -#ifdef GST_EXT_XV_ENHANCEMENT -#include -#include -#endif - -#include -#include -#include - -#include -#include -#include - -#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__ */ diff --git a/evaspixmapsink/xv_types.h b/evaspixmapsink/xv_types.h deleted file mode 100644 index 9ed7939..0000000 --- a/evaspixmapsink/xv_types.h +++ /dev/null @@ -1,41 +0,0 @@ -/* */ -/* 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; -} diff --git a/packaging/gst-plugins-tizen.spec b/packaging/gst-plugins-tizen.spec index a1d9283..1eb311c 100644 --- a/packaging/gst-plugins-tizen.spec +++ b/packaging/gst-plugins-tizen.spec @@ -56,7 +56,6 @@ export CFLAGS+=" -DGST_EXT_TIME_ANALYSIS -DGST_EXT_XV_ENHANCEMENT -DGST_WLSINK_E %configure \ %if %{with x} --disable-waylandsrc\ -# --disable-waylandsink\ %else --disable-xvimagesrc\ %endif diff --git a/waylandsink/Makefile.am b/waylandsink/Makefile.am deleted file mode 100644 index af437a6..0000000 --- a/waylandsink/Makefile.am +++ /dev/null @@ -1 +0,0 @@ -SUBDIRS = src diff --git a/waylandsink/src/Makefile.am b/waylandsink/src/Makefile.am deleted file mode 100644 index da44419..0000000 --- a/waylandsink/src/Makefile.am +++ /dev/null @@ -1,46 +0,0 @@ -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 diff --git a/waylandsink/src/gstwaylandsink.c b/waylandsink/src/gstwaylandsink.c deleted file mode 100644 index af4e6b0..0000000 --- a/waylandsink/src/gstwaylandsink.c +++ /dev/null @@ -1,1371 +0,0 @@ -/* GStreamer Wayland video sink - * - * Copyright (C) 2011 Intel Corporation - * Copyright (C) 2011 Sreerenj Balachandran - * Copyright (C) 2012 Wim Taymans - * 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 - * Wayland home page. - * The current implementaion is based on weston compositor. - * - * - * Example pipelines - * |[ - * gst-launch -v videotestsrc ! waylandsink - * ]| test the video rendering in wayland - * - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include "gstwaylandsink.h" -#ifdef GST_WLSINK_ENHANCEMENT -#include -#include "tizen-wlvideoformat.h" -#else -#include "wlvideoformat.h" -#endif -#include "waylandpool.h" - -#include -#include - -#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 , " - "George Kiagiadakis "); - - 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) diff --git a/waylandsink/src/gstwaylandsink.h b/waylandsink/src/gstwaylandsink.h deleted file mode 100644 index 92e8081..0000000 --- a/waylandsink/src/gstwaylandsink.h +++ /dev/null @@ -1,126 +0,0 @@ -/* - * GStreamer Wayland video sink - * Copyright (C) 2011 Intel Corporation - * Copyright (C) 2011 Sreerenj Balachandran - * - * 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 -#include - -#include - -#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("") -#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__ */ diff --git a/waylandsink/src/scaler.xml b/waylandsink/src/scaler.xml deleted file mode 100644 index e21ae5b..0000000 --- a/waylandsink/src/scaler.xml +++ /dev/null @@ -1,210 +0,0 @@ - - - - - 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. - - - - - 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. - - - - - 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. - - - - - - - - - - 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. - - - - - - - - - - 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. - - - - - The associated wl_surface's crop and scale state is removed. - The change is applied on the next wl_surface.commit. - - - - - - - - - - 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. - - - - - - - - - - - - - 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. - - - - - - - - - - - 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. - - - - - - - diff --git a/waylandsink/src/tizen-wlvideoformat.c b/waylandsink/src/tizen-wlvideoformat.c deleted file mode 100644 index 4c78c14..0000000 --- a/waylandsink/src/tizen-wlvideoformat.c +++ /dev/null @@ -1,113 +0,0 @@ -/* GStreamer Wayland video sink - * - * Copyright (C) 2011 Intel Corporation - * Copyright (C) 2011 Sreerenj Balachandran - * Copyright (C) 2012 Wim Taymans - * 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 -#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 diff --git a/waylandsink/src/tizen-wlvideoformat.h b/waylandsink/src/tizen-wlvideoformat.h deleted file mode 100644 index a62e7d8..0000000 --- a/waylandsink/src/tizen-wlvideoformat.h +++ /dev/null @@ -1,41 +0,0 @@ -/* GStreamer Wayland video sink - * - * Copyright (C) 2011 Intel Corporation - * Copyright (C) 2011 Sreerenj Balachandran - * Copyright (C) 2012 Wim Taymans - * 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 -#include - -#ifdef GST_WLSINK_ENHANCEMENT -#include - -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 diff --git a/waylandsink/src/waylandpool.c b/waylandsink/src/waylandpool.c deleted file mode 100644 index b36d2e2..0000000 --- a/waylandsink/src/waylandpool.c +++ /dev/null @@ -1,769 +0,0 @@ -/* GStreamer - * Copyright (C) 2012 Intel Corporation - * Copyright (C) 2012 Sreerenj Balachandran - * 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 -#include -#include -#include -#include -#include -#include -#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 diff --git a/waylandsink/src/waylandpool.h b/waylandsink/src/waylandpool.h deleted file mode 100644 index 85fdd0e..0000000 --- a/waylandsink/src/waylandpool.h +++ /dev/null @@ -1,111 +0,0 @@ -/* GStreamer Wayland buffer pool - * Copyright (C) 2012 Intel Corporation - * Copyright (C) 2012 Sreerenj Balachandran - * 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 -#include - -#include "wldisplay.h" -#ifdef GST_WLSINK_ENHANCEMENT -#include -#include -#include -#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("") -#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__*/ diff --git a/waylandsink/src/wldisplay.c b/waylandsink/src/wldisplay.c deleted file mode 100644 index 4a1ec63..0000000 --- a/waylandsink/src/wldisplay.c +++ /dev/null @@ -1,358 +0,0 @@ -/* 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 -#endif -#include "wldisplay.h" -#include - -#ifdef GST_WLSINK_ENHANCEMENT -#include -#include -#include -#include -#include - -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; -} diff --git a/waylandsink/src/wldisplay.h b/waylandsink/src/wldisplay.h deleted file mode 100644 index af99d8b..0000000 --- a/waylandsink/src/wldisplay.h +++ /dev/null @@ -1,102 +0,0 @@ -/* 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 -#include -#include "scaler-client-protocol.h" -#ifdef GST_WLSINK_ENHANCEMENT -#include -#include -#include -#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("") -#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__ */ diff --git a/waylandsink/src/wlvideoformat.c b/waylandsink/src/wlvideoformat.c deleted file mode 100644 index a0c3ff6..0000000 --- a/waylandsink/src/wlvideoformat.c +++ /dev/null @@ -1,114 +0,0 @@ -/* GStreamer Wayland video sink - * - * Copyright (C) 2011 Intel Corporation - * Copyright (C) 2011 Sreerenj Balachandran - * Copyright (C) 2012 Wim Taymans - * 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 -#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 diff --git a/waylandsink/src/wlvideoformat.h b/waylandsink/src/wlvideoformat.h deleted file mode 100644 index c03525b..0000000 --- a/waylandsink/src/wlvideoformat.h +++ /dev/null @@ -1,42 +0,0 @@ -/* GStreamer Wayland video sink - * - * Copyright (C) 2011 Intel Corporation - * Copyright (C) 2011 Sreerenj Balachandran - * Copyright (C) 2012 Wim Taymans - * 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 -#include - -#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 diff --git a/waylandsink/src/wlwindow.c b/waylandsink/src/wlwindow.c deleted file mode 100644 index 06af24d..0000000 --- a/waylandsink/src/wlwindow.c +++ /dev/null @@ -1,506 +0,0 @@ -/* GStreamer Wayland video sink - * - * Copyright (C) 2011 Intel Corporation - * Copyright (C) 2011 Sreerenj Balachandran - * 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 -#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 diff --git a/waylandsink/src/wlwindow.h b/waylandsink/src/wlwindow.h deleted file mode 100644 index 1af914e..0000000 --- a/waylandsink/src/wlwindow.h +++ /dev/null @@ -1,100 +0,0 @@ -/* 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 - -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("") -#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__ */ -- 2.7.4