From 7faccb97d69c7581e338f88ce3a2153cdd69fd16 Mon Sep 17 00:00:00 2001 From: Scott Murray Date: Fri, 8 Feb 2019 10:53:08 -0500 Subject: Upgrade to thud MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Changes include: - Add LAYERSERIES_COMPAT definitions to layer.conf files - Remove now unnecessary SECURITY_*FLAGS over-rides from distro configuration - Set intel-corei7-64 preferred kernel version to 4.19 to match latest linux-intel kernel available in meta-intel - Update qemuarm preferred kernel version to 4.18 to match latest linux-yocto - Update firmware package and devicetree file names for raspberrypi3 - Remove linux-firmware bbappend specific to raspberrypi, it seems no longer required and breaks the cross SDK build - Update linux-intel bbappend to 4.19, remove now unnecessary patch - Remove now unnecessary lttng-modules backport - Update linux-raspberrypi bbappend to 4.14 kernel - Added kernel configuration fragment for raspberrypi to disable Kprobes. This is required until linux-raspberrypi is updated to greater than 4.14.104 to avoid a build failure in lttng-modules related to a check for known breakage in the kernel CONFIG_OPTPROBES code. - Replace obsolete base_conditional usage with oe.utils.conditional - Add gstreamer1.0-plugins-bad bbappend for raspberrypi3 to disable faad PACKAGECONFIG to avoid commercial license issues - Remove unused and unbuildable Vayu gstreamer recipes - Update linux-ti-staging bbappend for new BSP kernel - Regen dcan2_pinmux_enable.patch for linux-ti-staging to remove fuzz warning, and remove upstreamed fix_dcan_addresses.patch - Remove ipumm-fw from meta-agl-bsp/meta-ti, as newer version is available in the upstream BSP - Update meta-agl-bsp/meta-ti weston patch to apply against 5.0.0 - Update meta-agl-bsp/meta-ti wayland-ivi-extension patch to apply against 2.2.0 - Add ti-sgx-ddk-km patch to add AGL toolchain configuration file - Remove now unnecessary fdtoverlay recipe - Update core.cfg and ivishell.cfg in weston-ini-conf recipe to handle move of ivi-controller.so configuration in Weston 5.0.0 - Update connman-ncurses patch to remove fuzz warning - Add installation of systemd over-ride file for run-postinsts.service in run-postinsts bbappend to workaround race condition between ldconfig.service and the /sbin/ldconfig invocations in the post-install scripts run by run-postinsts.service. The observed failure was cynara's post-install script failing and its database not being created. - Remove now unnecessary valgrind backport - Add patches to fix most driver compilation against newer kernels - Update libmicrohttpd bbappend - Remove libssp-dev from agl-image-graphical-qt5-crosssdk and agl-demo-platform-html5-crosssdk, upstream have removed it from non-mingw32 platform SDKs - Update wayland-ivi-extension recipe to build 2.2.0, and update local patches - Update weston patches for 5.0.0. Patches: 0016-ivi-shell_add_screen_remove_layer_api.patch 0017-ivi-shell-register-ivi_layout_interface.patch have been removed as they have been applied upstream and are no longer necessary. Patches: 0018-compositor-add-output-type-to-weston_output.patch 0019-compositor-drm-introduce-drm_get_dmafd_from_view.patch (both related to Waltham) have been disabled for now as they need significant rework. - Remove weston-conf RRECOMMENDS in weston bbappend to avoid conflict with weston-ini-conf - Add OECMAKE_GENERATOR = "Unix Makefiles" to aglwgt.bbclass to work around CMake+ninja issue in cmake-apps-module - Update dbus cynara patches for 1.12.10 - Add do_install_append in cynara recipe to remove /var/cynara from cynara package so the directory creation and labelling in the post-install scriptlet will function as intended - Remove now unnecessary e2fsprogs backport - Remove now unnecessary libcap-ng backport - Update pulseaudio patches to remove fuzz warnings - Update neardal patch to remove fuzz warning - Update freetype patch to remove fuzz warning - Rename opencv bbappend to 3.% to handle 3.x backports in upstream - Updated qtwayland patch to remove fuzz warning Changes from Stephane Desneux : - Remove wayland-ivi-extension PREFERRED_VERSION - Remove now unnecessary nativesdk-cmake patch - Remove now unnecessary ptest-runner patches - Remove now unnecessary harfbuzz patches - Disable waltham-transmitter as it does not build against weston 5.0.0 - Update af-main, cynara, and security-manager to use pkg_postinst_ontarget - Bump connman-ncurses revision to avoid deprecated ncurses functions - Update libva package usage with new intel-vaapi-driver name - Add patches to security-manager to fix compilation with gcc8 - Updated systemd bbappend Changes from Jan-Simon Möller : - Remove meta-agl-bsp/ROCKO.FIXMEs - Remove linux-yocto_4.12.bbappend and now unnecessary associated patch - Remove now unneeded kern-tools-native patch - Bump gstreamer PREFERRED_VERSIONs to 1.14.x - Remove latencytop from packagegroup-agl-core-devel, it has been dropped by upstream - Remove now unnecessary rpm patches - Update pulseaudio bbappend to 12.2 - Update opencv bbappend to 3.4 - Update freetype bbappend to 2.9.1 - Update dbus bbappend to 1.12.10 - Update weston bbappend to 5.0.0 - Update cynara patches to remove fuzz warnings - Add patch to cynara to fix compilation with gcc8 - Add xmlsec1 bbappend to clear EXTRA_OECONF to fix compilation on sumo or newer Changes from Ronan Le Martet : - Update meta-rcar-gen3-adas layer gstreamer1.0-plugin-vspfilter bbappend to version 1.0.1 Known issues (marked with FIXME): - CMake+ninja issue in cmake-apps-module has been worked around with OECMAKE_GENERATOR - waltham-transmitter and the patches to weston related to it have been disabled - Currently unclear if patch to libcap-native is actually required or not Bug-AGL: SPEC-1837 Change-Id: I7b8b9ef667aec2d229952eace6663dfc761654d0 Signed-off-by: Scott Murray --- ...gstkmssink-Add-support-for-KMS-based-sink.patch | 1592 -------------------- 1 file changed, 1592 deletions(-) delete mode 100644 meta-agl-bsp/meta-ti/recipes-arago/gstreamer/gstreamer1.0-plugins-bad/0003-gstkmssink-Add-support-for-KMS-based-sink.patch (limited to 'meta-agl-bsp/meta-ti/recipes-arago/gstreamer/gstreamer1.0-plugins-bad/0003-gstkmssink-Add-support-for-KMS-based-sink.patch') diff --git a/meta-agl-bsp/meta-ti/recipes-arago/gstreamer/gstreamer1.0-plugins-bad/0003-gstkmssink-Add-support-for-KMS-based-sink.patch b/meta-agl-bsp/meta-ti/recipes-arago/gstreamer/gstreamer1.0-plugins-bad/0003-gstkmssink-Add-support-for-KMS-based-sink.patch deleted file mode 100644 index 1068fda2c..000000000 --- a/meta-agl-bsp/meta-ti/recipes-arago/gstreamer/gstreamer1.0-plugins-bad/0003-gstkmssink-Add-support-for-KMS-based-sink.patch +++ /dev/null @@ -1,1592 +0,0 @@ -From 44ba6f9839a410e981c9c941f099316ebfac2659 Mon Sep 17 00:00:00 2001 -From: Pooja Prajod -Date: Fri, 20 Jan 2017 16:18:22 +0530 -Subject: [PATCH 3/5] gstkmssink: Add support for KMS based sink - -The following features are enabled: -1. Add support for kmssink -2. Fix memory leak by using API's that do not hold - reference to GstMemory -3. Restrict the number of buffers that will be allocated - by kmssink bufferpool -4. Use Atomic mode setting instead of SetPlane -5. Store encoder and plane data as static data to enable - same process looping usecase -6. Handle usecase where display is disabled by default - -Signed-off-by: Pooja Prajod ---- - configure.ac | 14 + - sys/Makefile.am | 10 +- - sys/kms/Makefile.am | 28 ++ - sys/kms/gstdrmutils.c | 347 +++++++++++++++++++++ - sys/kms/gstdrmutils.h | 50 +++ - sys/kms/gstkmsbufferpriv.c | 121 ++++++++ - sys/kms/gstkmsbufferpriv.h | 64 ++++ - sys/kms/gstkmssink.c | 740 +++++++++++++++++++++++++++++++++++++++++++++ - sys/kms/gstkmssink.h | 92 ++++++ - 9 files changed, 1464 insertions(+), 2 deletions(-) - create mode 100644 sys/kms/Makefile.am - create mode 100644 sys/kms/gstdrmutils.c - create mode 100644 sys/kms/gstdrmutils.h - create mode 100644 sys/kms/gstkmsbufferpriv.c - create mode 100644 sys/kms/gstkmsbufferpriv.h - create mode 100644 sys/kms/gstkmssink.c - create mode 100644 sys/kms/gstkmssink.h - -diff --git a/configure.ac b/configure.ac -index e254605..9fdfbc7 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -2324,6 +2324,18 @@ AG_GST_CHECK_FEATURE(KATE, [Kate], kate, [ - AC_SUBST(TIGER_LIBS) - ],,,[AM_CONDITIONAL(USE_TIGER, false)]) - -+ -+ -+dnl *** kms *** -+translit(dnm, m, l) AM_CONDITIONAL(USE_KMS, true) -+AG_GST_CHECK_FEATURE(KMS, [kmssink], kms, [ -+PKG_CHECK_MODULES([DRM], [libdrm libdrm_omap], HAVE_KMS=yes, HAVE_KMS=no) -+PKG_CHECK_MODULES(LIBDCE, [libdce >= 1.0.0], HAVE_KMS=yes, HAVE_KMS=no) -+AC_SUBST(DRM_CFLAGS) -+AC_SUBST(DRM_LIBS) -+]) -+ -+ - dnl *** ladspa *** - translit(dnm, m, l) AM_CONDITIONAL(USE_LADSPA, true) - AG_GST_CHECK_FEATURE(LADSPA, [ladspa], ladspa, [ -@@ -3383,6 +3395,7 @@ AM_CONDITIONAL(USE_GTK3_GL, false) - AM_CONDITIONAL(USE_HLS, false) - AM_CONDITIONAL(USE_KATE, false) - AM_CONDITIONAL(USE_TIGER, false) -+AM_CONDITIONAL(USE_KMS, false) - AM_CONDITIONAL(USE_LADSPA, false) - AM_CONDITIONAL(USE_LV2, false) - AM_CONDITIONAL(USE_LIBDE265, false) -@@ -3632,6 +3645,7 @@ sys/fbdev/Makefile - sys/linsys/Makefile - sys/nvenc/Makefile - sys/opensles/Makefile -+sys/kms/Makefile - sys/shm/Makefile - sys/tinyalsa/Makefile - sys/uvch264/Makefile -diff --git a/sys/Makefile.am b/sys/Makefile.am -index 32f79fb..325b4af 100644 ---- a/sys/Makefile.am -+++ b/sys/Makefile.am -@@ -87,6 +87,12 @@ PVR_DIR=pvr2d - else - PVR_DIR= - endif -+ -+if USE_KMS -+KMS_DIR=kms -+else -+KMS_DIR= -+endif - - if USE_SHM - SHM_DIR=shm -@@ -148,10 +154,10 @@ else - TINYALSA_DIR= - endif - --SUBDIRS = $(ACM_DIR) $(ANDROID_MEDIA_DIR) $(APPLE_MEDIA_DIR) $(AVC_DIR) $(BLUEZ_DIR) $(D3DVIDEOSINK_DIR) $(DECKLINK_DIR) $(DIRECTSOUND_DIR) $(WINKS_DIR) $(DVB_DIR) $(FBDEV_DIR) $(LINSYS_DIR) $(OPENSLES_DIR) $(PVR_DIR) $(SHM_DIR) $(UVCH264_DIR) $(VCD_DIR) $(VDPAU_DIR) $(WININET_DIR) $(WINSCREENCAP_DIR) $(WASAPI_DIR) $(NVENC_DIR) $(TINYALSA_DIR) -+SUBDIRS = $(ACM_DIR) $(ANDROID_MEDIA_DIR) $(APPLE_MEDIA_DIR) $(AVC_DIR) $(BLUEZ_DIR) $(D3DVIDEOSINK_DIR) $(DECKLINK_DIR) $(DIRECTSOUND_DIR) $(WINKS_DIR) $(DVB_DIR) $(FBDEV_DIR) $(LINSYS_DIR) $(OPENSLES_DIR) $(PVR_DIR) $(KMS_DIR) $(SHM_DIR) $(UVCH264_DIR) $(VCD_DIR) $(VDPAU_DIR) $(WININET_DIR) $(WINSCREENCAP_DIR) $(WASAPI_DIR) $(NVENC_DIR) $(TINYALSA_DIR) - - DIST_SUBDIRS = acmenc acmmp3dec androidmedia applemedia applemedia-nonpublic avc bluez d3dvideosink decklink directsound dvb linsys fbdev dshowdecwrapper dshowsrcwrapper dshowvideosink \ -- opensles pvr2d shm uvch264 vcd vdpau wasapi wininet winks winscreencap \ -+ opensles pvr2d kms shm uvch264 vcd vdpau wasapi wininet winks winscreencap \ - nvenc tinyalsa - - include $(top_srcdir)/common/parallel-subdirs.mak -diff --git a/sys/kms/Makefile.am b/sys/kms/Makefile.am -new file mode 100644 -index 0000000..6d56073 ---- /dev/null -+++ b/sys/kms/Makefile.am -@@ -0,0 +1,28 @@ -+plugin_LTLIBRARIES = libgstkmssink.la -+ -+libgstkmssink_la_SOURCES = \ -+ gstkmssink.c \ -+ gstkmsbufferpriv.c \ -+ gstdrmutils.c -+ -+libgstkmssink_la_CFLAGS = \ -+ $(GST_PLUGINS_BAD_CFLAGS) \ -+ $(GST_PLUGINS_BASE_CFLAGS) \ -+ $(GST_BASE_CFLAGS) \ -+ $(LIBDCE_CFLAGS) \ -+ $(GST_CFLAGS) \ -+ $(DRM_CFLAGS) -+ -+libgstkmssink_la_LIBADD = \ -+ $(GST_PLUGINS_BASE_LIBS) \ -+ $(GST_BASE_LIBS) \ -+ $(GST_LIBS) \ -+ $(LIBDCE_LIBS) \ -+ $(DRM_LIBS) \ -+ -lgstvideo-$(GST_API_VERSION) \ -+ $(top_builddir)/gst-libs/gst/drm/libgstdrm-$(GST_API_VERSION).la -+ -+libgstkmssink_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) -+libgstkmssink_la_LIBTOOLFLAGS = --tag=disable-static -+ -+noinst_HEADERS = gstkmssink.h gstdrmutils.h gstkmsbufferpriv.h -diff --git a/sys/kms/gstdrmutils.c b/sys/kms/gstdrmutils.c -new file mode 100644 -index 0000000..0e67a48 ---- /dev/null -+++ b/sys/kms/gstdrmutils.c -@@ -0,0 +1,347 @@ -+/* GStreamer -+ * -+ * Copyright (C) 2012 Texas Instruments -+ * Copyright (C) 2012 Collabora Ltd -+ * -+ * Authors: -+ * Alessandro Decina -+ * -+ * This library is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU Library General Public -+ * License as published by the Free Software Foundation; either -+ * version 2 of the License, or (at your option) any later version. -+ * -+ * This library is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * Library General Public License for more details. -+ * -+ * You should have received a copy of the GNU Library General Public -+ * License along with this library; if not, write to the -+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330, -+ * Boston, MA 02111-1307, USA. -+ */ -+ -+#include -+#include "gstdrmutils.h" -+ -+static int stored_enc = 0; -+static drmModeEncoder *enc; -+static struct plane_data *stored_plane; -+ -+GST_DEBUG_CATEGORY_EXTERN (gst_debug_kms_sink); -+#define GST_CAT_DEFAULT gst_debug_kms_sink -+ -+void -+gst_drm_connector_cleanup (int fd, struct connector *c) -+{ -+ if (c->connector) { -+ drmModeFreeConnector (c->connector); -+ c->connector = NULL; -+ } -+ -+ if (c->fb_id) { -+ drmModeRmFB (fd, c->fb_id); -+ c->fb_id = 0; -+ } -+ if (c->fb_bo) { -+ omap_bo_del (c->fb_bo); -+ c->fb_bo = NULL; -+ } -+} -+ -+ -+static gboolean -+gst_drm_connector_find_mode_and_plane_helper (int fd, -+ struct omap_device *dev, int width, int height, -+ drmModeRes * resources, drmModePlaneRes * plane_resources, -+ struct connector *c) -+{ -+ int i, best_area = 0, ret; -+ struct drm_set_client_cap req; -+ unsigned int j; -+ int32_t crtc; -+ -+ gst_drm_connector_cleanup (fd, c); -+ -+ req.capability = DRM_CLIENT_CAP_ATOMIC; -+ req.value = 1; -+ ret = ioctl(fd, DRM_IOCTL_SET_CLIENT_CAP, &req); -+ if(ret < 0) { -+ GST_DEBUG("drm set atomic cap failed"); -+ goto fail; -+ } -+ -+ /* First, find the connector & mode */ -+ c->connector = drmModeGetConnector (fd, c->id); -+ if (!c->connector) -+ goto error_no_connector; -+ -+ if (!c->connector->count_modes) -+ goto error_no_mode; -+ -+ /* just look for the highest resolution: */ -+ for (i = 0; i < c->connector->count_modes; i++) { -+ drmModeModeInfo *mode = &c->connector->modes[i]; -+ int area = mode->hdisplay * mode->vdisplay; -+ -+ if (area > best_area) { -+ c->mode = mode; -+ best_area = area; -+ } -+ } -+ -+ if (c->mode == NULL) { -+ /* XXX: just pick the first available mode. Not sure this is correct... */ -+ c->mode = &c->connector->modes[0]; -+#if 0 -+ goto error_no_mode; -+#endif -+ } -+ -+ /* Now get the encoder */ -+ -+ if (stored_enc) { -+ c->encoder = enc; -+ c->connector->encoder_id = stored_enc; -+ } else { -+ c->encoder = drmModeGetEncoder (fd, c->connector->encoder_id); -+ enc = c->encoder; -+ stored_enc = c->connector->encoder_id; -+ } -+ -+ if (!c->encoder) { -+ for (i = 0; i < c->connector->count_encoders; ++i) { -+ c->encoder = drmModeGetEncoder(fd, c->connector->encoders[i]); -+ if (!c->encoder) { -+ GST_DEBUG ("Cannot retrieve encoder %u:%u (%d): %m\n", -+ i, c->connector->encoders[i], errno); -+ continue; -+ } -+ /* iterate all global CRTCs */ -+ for (j = 0; j < resources->count_crtcs; ++j) { -+ /* check whether this CRTC works with the encoder */ -+ if (!(c->encoder->possible_crtcs & (1 << j))) -+ continue; -+ crtc = resources->crtcs[j]; -+ break; -+ } -+ if (crtc >= 0) { -+ enc = c->encoder; -+ stored_enc = c->connector->encoder_id; -+ c->crtc = crtc; -+ goto found_encoder; -+ } -+ } -+ } -+ -+found_encoder: -+ -+ if (!c->encoder) -+ goto error_no_encoder; -+ -+ if (c->crtc == -1) -+ c->crtc = c->encoder->crtc_id; -+ -+ /* and figure out which crtc index it is: */ -+ c->pipe = -1; -+ for (i = 0; i < resources->count_crtcs; i++) { -+ if (c->crtc == (int) resources->crtcs[i]) { -+ c->pipe = i; -+ break; -+ } -+ } -+ -+ if (c->pipe == -1) -+ goto error_no_crtc; -+ -+ if (stored_plane) { -+ c->pdata = stored_plane; -+ } else { -+ -+ c->pdata = calloc(sizeof(struct plane_data), 1); -+ for (i = 0; i < plane_resources->count_planes; i++) { -+ drmModePlane *plane = drmModeGetPlane (fd, plane_resources->planes[i]); -+ int propc; -+ if (plane->possible_crtcs & (1 << c->pipe)) { -+ drmModeObjectPropertiesPtr props = drmModeObjectGetProperties(fd, plane_resources->planes[i], DRM_MODE_OBJECT_PLANE); -+ for(propc = 0; propc < props->count_props; propc++) { -+ drmModePropertyPtr prop = drmModeGetProperty(fd, props->props[propc]); -+ if(strcmp(prop->name, "FB_ID") == 0) -+ c->pdata[0].fb_id_property = props->props[propc]; -+ } -+ c->pdata[0].plane = plane_resources->planes[i]; -+ stored_plane = c->pdata; -+ break; -+ } -+ } -+ if (stored_plane == NULL) -+ goto error_no_plane; -+ } -+ c->fb_bo = omap_bo_new (dev, best_area * 2, OMAP_BO_WC); -+ if (c->fb_bo) { -+ uint32_t fourcc = DRM_FORMAT_RGB565; -+ uint32_t handles[4] = { omap_bo_handle (c->fb_bo) }; -+ uint32_t pitches[4] = { c->mode->hdisplay * 2 }; -+ uint32_t offsets[4] = { 0 }; -+ ret = drmModeAddFB2 (fd, c->mode->hdisplay, c->mode->vdisplay, -+ fourcc, handles, pitches, offsets, &c->fb_id, 0); -+ if (ret) { -+ GST_DEBUG ("RGB565 AddFb2 failed"); -+ } -+ } -+ -+ /* now set the desired mode: */ -+ ret = drmModeSetCrtc (fd, c->crtc, c->fb_id, 0, 0, &c->id, 1, c->mode); -+ if (ret) { -+ GST_DEBUG ("SetCrtc failed"); -+ } -+ -+ return TRUE; -+ -+fail: -+ gst_drm_connector_cleanup (fd, c); -+ -+ return FALSE; -+ -+error_no_connector: -+ GST_DEBUG ("could not get connector %s", strerror (errno)); -+ goto fail; -+ -+error_no_mode: -+ GST_DEBUG ("could not find mode %dx%d (count_modes %d)", -+ width, height, c->connector->count_modes); -+ goto fail; -+ -+error_no_encoder: -+ GST_DEBUG ("could not get encoder: %s", strerror (errno)); -+ goto fail; -+ -+error_no_crtc: -+ GST_DEBUG ("couldn't find a crtc"); -+ goto fail; -+ -+error_no_plane: -+ GST_DEBUG ("couldn't find a plane"); -+ goto fail; -+} -+ -+gboolean -+gst_drm_connector_find_mode_and_plane (int fd, -+ struct omap_device *dev, int width, int height, -+ drmModeRes * resources, drmModePlaneRes * plane_resources, -+ struct connector *c) -+{ -+ int i; -+ gboolean found = FALSE; -+ -+ /* First, find the connector & mode */ -+ if (c->id == 0) { -+ /* Any connector */ -+ GST_DEBUG ("Any connector, %d available", resources->count_connectors); -+ for (i = 0; i < resources->count_connectors; i++) { -+ GST_DEBUG (" %d", resources->connectors[i]); -+ } -+ for (i = 0; i < resources->count_connectors; i++) { -+ GST_DEBUG ("Trying connector %d: %d", i, resources->connectors[i]); -+ c->id = resources->connectors[i]; -+ if (gst_drm_connector_find_mode_and_plane_helper (fd, dev, width, height, -+ resources, plane_resources, c)) { -+ GST_DEBUG ("Found suitable connector"); -+ found = TRUE; -+ break; -+ } -+ GST_DEBUG ("Connector not suitable"); -+ } -+ } else { -+ /* A specific connector */ -+ GST_DEBUG ("Connector %d", c->id); -+ found = -+ gst_drm_connector_find_mode_and_plane_helper (fd, dev, width, height, -+ resources, plane_resources, c); -+ } -+ -+ return found; -+} -+ -+/* table nicked off libdrm's modetest.c */ -+/* *INDENT-OFF* */ -+static const struct { -+ int type_id; -+ const char *type_name; -+} connector_type_names[] = { -+ { DRM_MODE_CONNECTOR_Unknown, "unknown" }, -+ { DRM_MODE_CONNECTOR_VGA, "VGA" }, -+ { DRM_MODE_CONNECTOR_DVII, "DVI-I" }, -+ { DRM_MODE_CONNECTOR_DVID, "DVI-D" }, -+ { DRM_MODE_CONNECTOR_DVIA, "DVI-A" }, -+ { DRM_MODE_CONNECTOR_Composite, "composite" }, -+ { DRM_MODE_CONNECTOR_SVIDEO, "s-video" }, -+ { DRM_MODE_CONNECTOR_LVDS, "LVDS" }, -+ { DRM_MODE_CONNECTOR_Component, "component" }, -+ { DRM_MODE_CONNECTOR_9PinDIN, "9-pin-DIN" }, -+ { DRM_MODE_CONNECTOR_DisplayPort, "displayport" }, -+ { DRM_MODE_CONNECTOR_HDMIA, "HDMI-A" }, -+ { DRM_MODE_CONNECTOR_HDMIB, "HDMI-B" }, -+ { DRM_MODE_CONNECTOR_TV, "TV" }, -+ { DRM_MODE_CONNECTOR_eDP, "embedded-displayport" }, -+}; -+/* *INDENT-ON* */ -+ -+gboolean -+gst_drm_connector_find_mode_and_plane_by_name (int fd, -+ struct omap_device * dev, int width, int height, -+ drmModeRes * resources, drmModePlaneRes * plane_resources, -+ struct connector * c, const char *name) -+{ -+ int i, n; -+ char tmp[64]; -+ const char *type_name; -+ int found[G_N_ELEMENTS (connector_type_names)] = { 0 }; -+ -+ /* Find connector from name */ -+ for (i = 0; i < resources->count_connectors; i++) { -+ GST_DEBUG ("Trying connector %d: %d", i, resources->connectors[i]); -+ c->id = resources->connectors[i]; -+ c->connector = drmModeGetConnector (fd, c->id); -+ if (!c->connector) -+ continue; -+ -+ /* Find type name from this connector */ -+ for (n = 0; n < G_N_ELEMENTS (connector_type_names); n++) -+ if (connector_type_names[n].type_id == c->connector->connector_type) -+ break; -+ if (n == G_N_ELEMENTS (connector_type_names)) -+ continue; -+ -+ type_name = connector_type_names[n].type_name; -+ GST_DEBUG ("Connector %d has type %s", i, type_name); -+ ++found[n]; -+ -+ drmModeFreeConnector (c->connector); -+ c->connector = NULL; -+ -+ /* Try a few different matches, such as modetest and xrandr -+ output, and also a indexless one matching first found */ -+ snprintf (tmp, sizeof (tmp), "%s-%u", type_name, found[n]); -+ if (!g_ascii_strcasecmp (tmp, name)) -+ goto found; -+ snprintf (tmp, sizeof (tmp), "%s%u", type_name, found[n]); -+ if (!g_ascii_strcasecmp (tmp, name)) -+ goto found; -+ if (!g_ascii_strcasecmp (name, type_name)) -+ goto found; -+ -+ continue; -+ -+ found: -+ if (gst_drm_connector_find_mode_and_plane_helper (fd, dev, width, height, -+ resources, plane_resources, c)) { -+ GST_DEBUG ("Found suitable connector"); -+ return TRUE; -+ } -+ GST_DEBUG ("Connector not suitable"); -+ } -+ -+ return FALSE; -+} -diff --git a/sys/kms/gstdrmutils.h b/sys/kms/gstdrmutils.h -new file mode 100644 -index 0000000..ebc5fc6 ---- /dev/null -+++ b/sys/kms/gstdrmutils.h -@@ -0,0 +1,50 @@ -+#ifndef __GST_DRMUTILS_H__ -+#define __GST_DRMUTILS_H__ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+struct plane_data { -+ int plane; -+ int fb_id_property; -+}; -+ -+struct connector { -+ uint32_t id; -+ char mode_str[64]; -+ drmModeConnector *connector; -+ drmModeModeInfo *mode; -+ drmModeEncoder *encoder; -+ uint32_t fb_id; -+ struct omap_bo *fb_bo; -+ int crtc; -+ int pipe; -+ struct plane_data *pdata; -+}; -+ -+void gst_drm_connector_cleanup (int fd, struct connector * c); -+gboolean gst_drm_connector_find_mode_and_plane (int fd, -+ struct omap_device * dev, int width, int height, -+ drmModeRes * resources, drmModePlaneRes * plane_resources, -+ struct connector *c); -+gboolean gst_drm_connector_find_mode_and_plane_by_name (int fd, -+ struct omap_device *dev, int width, int height, -+ drmModeRes * resources, drmModePlaneRes * plane_resources, -+ struct connector *c, const char *name); -+ -+#endif /* __GST_DRMUTILS_H__ */ -diff --git a/sys/kms/gstkmsbufferpriv.c b/sys/kms/gstkmsbufferpriv.c -new file mode 100644 -index 0000000..172a4c3 ---- /dev/null -+++ b/sys/kms/gstkmsbufferpriv.c -@@ -0,0 +1,121 @@ -+/* -+ * GStreamer -+ * -+ * Copyright (C) 2012 Texas Instruments -+ * Copyright (C) 2012 Collabora Ltd -+ * -+ * Authors: -+ * Alessandro Decina -+ * Rob Clark -+ * -+ * 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 -+ * version 2.1 of the License. -+ * -+ * 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 -+ -+#include -+#include -+#include -+ -+#include -+#include -+#include -+ -+#include "gstkmssink.h" -+#include "gstkmsbufferpriv.h" -+ -+static int -+create_fb (GstKMSBufferPriv * priv, GstKMSSink * sink) -+{ -+ /* TODO get format, etc from caps.. and query device for -+ * supported formats, and make this all more flexible to -+ * cope with various formats: -+ */ -+ uint32_t fourcc = GST_MAKE_FOURCC ('N', 'V', '1', '2'); -+ -+ uint32_t handles[4] = { -+ omap_bo_handle (priv->bo), omap_bo_handle (priv->bo), -+ }; -+ uint32_t pitches[4] = { -+ GST_ROUND_UP_4 (sink->input_width), GST_ROUND_UP_4 (sink->input_width), -+ }; -+ uint32_t offsets[4] = { -+ 0, pitches[0] * sink->input_height -+ }; -+ -+ return drmModeAddFB2 (priv->fd, sink->input_width, sink->input_height, -+ fourcc, handles, pitches, offsets, &priv->fb_id, 0); -+} -+ -+/** -+ * gst_kms_buffer_priv: -+ * @sink: a #GstKMSSink -+ * @buf: a pointer to #GstBuffer -+ * -+ * Checks if the @buf has a GstMetaDmaBuf metadata set. If it doesn't we return a NULL -+ * indicating its not a dmabuf buffer. We maintain a hashtable with dmabuf fd as key and -+ * the GstKMSBufferPriv structure as value -+ * -+ * Returns: the #GstKMSBufferPriv -+ * -+ * Since: 1.2.? -+ */ -+GstKMSBufferPriv * -+gst_kms_buffer_priv (GstKMSSink * sink, GstBuffer * buf) -+{ -+ struct omap_bo *bo; -+ int fd; -+ int fd_copy; -+ GstKMSBufferPriv * priv; -+ GstMemory *mem; -+ -+ /* if it isn't a dmabuf buffer that we can import, then there -+ * is nothing we can do with it: -+ */ -+ mem = gst_buffer_peek_memory (buf, 0); -+ fd_copy = gst_fd_memory_get_fd (mem); -+ if (fd_copy < 0) { -+ GST_DEBUG_OBJECT (sink, "not importing non dmabuf buffer"); -+ return NULL; -+ } -+ -+ /* lookup the hashtable with fd as key. If present return bo & buffer structure */ -+ priv = g_hash_table_lookup (sink->kmsbufferpriv, (gpointer)fd_copy); -+ if(priv) { -+ return priv; -+ } -+ -+ priv = g_malloc0 (sizeof (GstKMSBufferPriv)); -+ bo = omap_bo_from_dmabuf (sink->dev, fd_copy); -+ fd = sink->fd; -+ -+ priv->bo = bo; -+ priv->fd = fd; -+ -+ if (create_fb (priv, sink)) { -+ GST_WARNING_OBJECT (sink, "could not create framebuffer: %s", -+ strerror (errno)); -+ g_free(priv); -+ return NULL; -+ } -+ -+ /* if fd not present, write to hash table fd and the corresponding priv. */ -+ g_hash_table_insert(sink->kmsbufferpriv, (gpointer)fd_copy, priv); -+ -+ -+ return priv; -+} -diff --git a/sys/kms/gstkmsbufferpriv.h b/sys/kms/gstkmsbufferpriv.h -new file mode 100644 -index 0000000..a1070da ---- /dev/null -+++ b/sys/kms/gstkmsbufferpriv.h -@@ -0,0 +1,64 @@ -+/* -+ * GStreamer -+ * -+ * Copyright (C) 2012 Texas Instruments -+ * Copyright (C) 2012 Collabora Ltd -+ * -+ * Authors: -+ * Alessandro Decina -+ * Rob Clark -+ * -+ * 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 -+ * version 2.1 of the License. -+ * -+ * 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 __GSTKMSBUFFERPRIV_H__ -+#define __GSTKMSBUFFERPRIV_H__ -+ -+#include -+#include -+ -+G_BEGIN_DECLS -+ -+/* -+ * per-buffer private data so kmssink can attach a drm_framebuffer -+ * handle (fb_id) to a buffer, which gets deleted when the buffer -+ * is finalized -+ */ -+ -+#define GST_TYPE_KMS_BUFFER_PRIV \ -+ (gst_kms_buffer_priv_get_type ()) -+#define GST_KMS_BUFFER_PRIV(obj) \ -+ (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_KMS_BUFFER_PRIV, GstKMSBufferPriv)) -+#define GST_IS_KMS_BUFFER_PRIV(obj) \ -+ (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_KMS_BUFFER_PRIV)) -+ -+ -+typedef struct -+{ -+ struct omap_bo *bo; -+ int fd; -+ uint32_t fb_id; -+}GstKMSBufferPriv; -+ -+ -+GType gst_kms_buffer_priv_get_type (void); -+ -+/* Returns a GstKMSBufferPriv, if it has a dmabuf fd metadata */ -+GstKMSBufferPriv * gst_kms_buffer_priv (GstKMSSink *sink, GstBuffer * buf); -+ -+G_END_DECLS -+ -+ -+#endif /* __GSTKMSBUFFERPRIV_H__ */ -diff --git a/sys/kms/gstkmssink.c b/sys/kms/gstkmssink.c -new file mode 100644 -index 0000000..17e6407 ---- /dev/null -+++ b/sys/kms/gstkmssink.c -@@ -0,0 +1,740 @@ -+/* GStreamer -+ * Copyright (C) 2012 Texas Instruments -+ * Copyright (C) 2012 Collabora Ltd -+ * -+ * Authors: -+ * Alessandro Decina -+ * -+ * This library is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU Library General Public -+ * License as published by the Free Software Foundation; either -+ * version 2 of the License, or (at your option) any later version. -+ * -+ * This library is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * Library General Public License for more details. -+ * -+ * You should have received a copy of the GNU Library General Public -+ * License along with this library; if not, write to the -+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330, -+ * Boston, MA 02111-1307, USA. -+ * -+ * Authors: -+ * Alessandro Decina -+ */ -+ -+#ifdef HAVE_CONFIG_H -+#include "config.h" -+#endif -+ -+#include "gstkmssink.h" -+#include "gstkmsbufferpriv.h" -+ -+#include -+#include -+#include -+#include -+ -+static int drm_fd = -1; -+static struct omap_device *drm_dev; -+static int once =1; -+ -+GST_DEBUG_CATEGORY (gst_debug_kms_sink); -+#define GST_CAT_DEFAULT gst_debug_kms_sink -+ -+G_DEFINE_TYPE (GstKMSSink, gst_kms_sink, GST_TYPE_VIDEO_SINK); -+ -+static void gst_kms_sink_reset (GstKMSSink * sink); -+ -+static GstStaticPadTemplate gst_kms_sink_template_factory = -+GST_STATIC_PAD_TEMPLATE ("sink", -+ GST_PAD_SINK, -+ GST_PAD_ALWAYS, -+ GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE("NV12")) -+ ); -+ -+enum -+{ -+ PROP_0, -+ PROP_PIXEL_ASPECT_RATIO, -+ PROP_FORCE_ASPECT_RATIO, -+ PROP_SCALE, -+ PROP_CONNECTOR, -+ PROP_CONNECTOR_NAME, -+}; -+ -+ -+static inline void -+display_bufs_queue (GstKMSSink * sink, GstBuffer * buf) -+{ -+ int i; -+ for (i = 0; i < (NUM_DISPLAY_BUFS - 1); i++) -+ gst_buffer_replace (&sink->display_bufs[i], sink->display_bufs[i + 1]); -+ gst_buffer_replace (&sink->display_bufs[i], buf); -+} -+ -+static inline void -+display_bufs_free (GstKMSSink * sink) -+{ -+ int i; -+ for (i = 0; i < NUM_DISPLAY_BUFS; i++) -+ gst_buffer_replace (&sink->display_bufs[i], NULL); -+} -+ -+static gboolean -+gst_kms_sink_calculate_aspect_ratio (GstKMSSink * sink, gint width, -+ gint height, gint video_par_n, gint video_par_d) -+{ -+ guint calculated_par_n; -+ guint calculated_par_d; -+ -+ if (!gst_video_calculate_display_ratio (&calculated_par_n, &calculated_par_d, -+ width, height, video_par_n, video_par_d, 1, 1)) { -+ GST_ELEMENT_ERROR (sink, CORE, NEGOTIATION, (NULL), -+ ("Error calculating the output display ratio of the video.")); -+ return FALSE; -+ } -+ GST_DEBUG_OBJECT (sink, -+ "video width/height: %dx%d, calculated display ratio: %d/%d", -+ width, height, calculated_par_n, calculated_par_d); -+ -+ /* 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 = calculated_pad_n / calculated_par_d */ -+ -+ /* start with same height, because of interlaced video */ -+ /* check hd / calculated_par_d is an integer scale factor, and scale wd with the PAR */ -+ if (height % calculated_par_d == 0) { -+ GST_DEBUG_OBJECT (sink, "keeping video height"); -+ GST_VIDEO_SINK_WIDTH (sink) = (guint) -+ gst_util_uint64_scale_int (height, calculated_par_n, calculated_par_d); -+ GST_VIDEO_SINK_HEIGHT (sink) = height; -+ } else if (width % calculated_par_n == 0) { -+ GST_DEBUG_OBJECT (sink, "keeping video width"); -+ GST_VIDEO_SINK_WIDTH (sink) = width; -+ GST_VIDEO_SINK_HEIGHT (sink) = (guint) -+ gst_util_uint64_scale_int (width, calculated_par_d, calculated_par_n); -+ } else { -+ GST_DEBUG_OBJECT (sink, "approximating while keeping video height"); -+ GST_VIDEO_SINK_WIDTH (sink) = (guint) -+ gst_util_uint64_scale_int (height, calculated_par_n, calculated_par_d); -+ GST_VIDEO_SINK_HEIGHT (sink) = height; -+ } -+ GST_DEBUG_OBJECT (sink, "scaling to %dx%d", -+ GST_VIDEO_SINK_WIDTH (sink), GST_VIDEO_SINK_HEIGHT (sink)); -+ -+ return TRUE; -+} -+ -+static gboolean -+gst_kms_sink_setcaps (GstBaseSink * bsink, GstCaps * caps) -+{ -+ GstKMSSink *sink; -+ gboolean ret = TRUE; -+ gint width, height; -+ gint fps_n, fps_d; -+ gint par_n, par_d; -+ GstVideoFormat format; -+ GstVideoInfo info; -+ GstStructure *conf; -+ GstStructure *s; -+ int size; -+ -+ sink = GST_KMS_SINK (bsink); -+ -+ ret = gst_video_info_from_caps (&info, caps); -+ format = GST_VIDEO_INFO_FORMAT(&info); -+ width = GST_VIDEO_INFO_WIDTH(&info); -+ height = GST_VIDEO_INFO_HEIGHT(&info); -+ fps_n = GST_VIDEO_INFO_FPS_N(&info); -+ fps_d = GST_VIDEO_INFO_FPS_D(&info); -+ par_n = GST_VIDEO_INFO_PAR_N(&info); -+ par_d = GST_VIDEO_INFO_PAR_D(&info); -+ -+ if (!ret) -+ return FALSE; -+ -+ if (width <= 0 || height <= 0) { -+ GST_ELEMENT_ERROR (sink, CORE, NEGOTIATION, (NULL), -+ ("Invalid image size.")); -+ return FALSE; -+ } -+ -+ sink->format = format; -+ sink->par_n = par_n; -+ sink->par_d = par_d; -+ sink->src_rect.x = sink->src_rect.y = 0; -+ sink->src_rect.w = width; -+ sink->src_rect.h = height; -+ sink->input_width = width; -+ sink->input_height = height; -+ size = info.size; -+ -+ if (!sink->pool) { -+ GstAllocator *allocator; -+ -+ allocator = gst_drm_allocator_get (); -+ sink->pool = gst_buffer_pool_new (); -+ conf = gst_buffer_pool_get_config (GST_BUFFER_POOL(sink->pool)); -+ gst_buffer_pool_config_set_params (conf, caps, size, 0, 0); -+ gst_buffer_pool_config_set_allocator (conf, allocator, NULL); -+ gst_buffer_pool_set_config (GST_BUFFER_POOL(sink->pool), conf); -+ if (allocator) -+ gst_object_unref (allocator); -+ } -+ -+ sink->conn.crtc = -1; -+ return TRUE; -+} -+ -+static void -+gst_kms_sink_get_times (GstBaseSink * bsink, GstBuffer * buf, -+ GstClockTime * start, GstClockTime * end) -+{ -+ GstKMSSink *sink; -+ -+ sink = GST_KMS_SINK (bsink); -+ -+ if (GST_BUFFER_PTS_IS_VALID (buf)) { -+ *start = GST_BUFFER_PTS (buf); -+ if (GST_BUFFER_DURATION_IS_VALID (buf)) { -+ *end = *start + GST_BUFFER_DURATION (buf); -+ } else { -+ if (sink->fps_n > 0) { -+ *end = *start + -+ gst_util_uint64_scale_int (GST_SECOND, sink->fps_d, sink->fps_n); -+ } -+ } -+ } -+} -+ -+ -+static void page_flip_handler(int fd, unsigned int frame, -+ unsigned int sec, unsigned int usec, void *data) -+{ -+ int *waiting_for_flip = data; -+ *waiting_for_flip = 0; -+} -+ -+ -+static GstFlowReturn -+gst_kms_sink_show_frame (GstVideoSink * vsink, GstBuffer * inbuf) -+{ -+ GstKMSSink *sink = GST_KMS_SINK (vsink); -+ GstBuffer *buf = NULL; -+ GstKMSBufferPriv *priv; -+ GstFlowReturn flow_ret = GST_FLOW_OK; -+ int ret = 0; -+ gint width, height; -+ GstVideoRectangle *c = &sink->src_rect; -+ int waiting_for_flip = 1; -+ -+ fd_set fds; -+ drmEventContext evctx = { -+ .version = DRM_EVENT_CONTEXT_VERSION, -+ .vblank_handler = 0, -+ .page_flip_handler = page_flip_handler, -+ }; -+ -+ g_mutex_lock (&sink->render_lock); -+ GstVideoCropMeta* crop = gst_buffer_get_video_crop_meta (inbuf); -+ if (crop){ -+ c->y = crop->y; -+ c->x = crop->x; -+ -+ if (crop->width >= 0) { -+ width = crop->width; -+ } else { -+ width = sink->input_width; -+ } -+ if (crop->height >= 0){ -+ height = crop->height; -+ } else { -+ height = sink->input_height; -+ } -+ } else { -+ width = sink->input_width; -+ height = sink->input_height; -+ } -+ -+ c->w = width; -+ c->h = height; -+ -+ -+ if (!gst_kms_sink_calculate_aspect_ratio (sink, width, height, -+ sink->par_n, sink->par_d)) -+ GST_DEBUG_OBJECT (sink, "calculate aspect ratio failed"); -+ -+ -+ GST_INFO_OBJECT (sink, "enter"); -+ -+ if (sink->conn.crtc == -1) { -+ if (sink->conn_name) { -+ if (!gst_drm_connector_find_mode_and_plane_by_name (sink->fd, -+ sink->dev, sink->src_rect.w, sink->src_rect.h, -+ sink->resources, sink->plane_resources, &sink->conn, -+ sink->conn_name)) -+ goto connector_not_found; -+ } else { -+ sink->conn.id = sink->conn_id; -+ if (!gst_drm_connector_find_mode_and_plane (sink->fd, -+ sink->dev, sink->src_rect.w, sink->src_rect.h, -+ sink->resources, sink->plane_resources, &sink->conn)) -+ goto connector_not_found; -+ } -+ once = 1; -+ } -+ -+ priv = gst_kms_buffer_priv (sink, inbuf); -+ -+ if (priv) { -+ buf = inbuf; -+ } else { -+ GST_LOG_OBJECT (sink, "not a KMS buffer, slow-path!"); -+ gst_buffer_pool_acquire_buffer (sink->pool, &buf, NULL); -+ if (buf) { -+ GST_BUFFER_PTS (buf) = GST_BUFFER_PTS (inbuf); -+ GST_BUFFER_DURATION (buf) = GST_BUFFER_DURATION (inbuf); -+ gst_buffer_copy_into (buf, inbuf, GST_BUFFER_COPY_DEEP, 0 ,-1); -+ priv = gst_kms_buffer_priv (sink, buf); -+ } -+ if (!priv) -+ goto add_fb2_failed; -+ } -+ -+ if (once) { -+ once = 0; -+ static GstVideoRectangle dest = { 0 }; -+ dest.w = sink->conn.mode->hdisplay; -+ dest.h = sink->conn.mode->vdisplay; -+ -+ gst_video_sink_center_rect (sink->src_rect, dest, &sink->dst_rect, -+ sink->scale); -+ ret = drmModeSetPlane (sink->fd, sink->conn.pdata[0].plane, -+ sink->conn.crtc, priv->fb_id, 0, -+ sink->dst_rect.x, sink->dst_rect.y, sink->dst_rect.w, sink->dst_rect.h, -+ sink->src_rect.x << 16, sink->src_rect.y << 16, -+ sink->src_rect.w << 16, sink->src_rect.h << 16); -+ if (ret) -+ goto set_plane_failed; -+ } -+ -+ drmModeAtomicReqPtr m_req = drmModeAtomicAlloc(); -+ -+ drmModeAtomicAddProperty(m_req, sink->conn.pdata[0].plane, -+ sink->conn.pdata[0].fb_id_property, -+ priv->fb_id); -+ -+ drmModeAtomicCommit(sink->fd, m_req, DRM_MODE_ATOMIC_TEST_ONLY, 0); -+ drmModeAtomicCommit(sink->fd, m_req, DRM_MODE_PAGE_FLIP_EVENT | DRM_MODE_ATOMIC_NONBLOCK, &waiting_for_flip); -+ drmModeAtomicFree(m_req); -+ -+ while (waiting_for_flip) { -+ FD_ZERO(&fds); -+ FD_SET(sink->fd, &fds); -+ int err; -+ err = select(sink->fd + 1, &fds, NULL, NULL, NULL); -+ if (err < 0) { -+ GST_ERROR_OBJECT (sink,"select err: %s\n", strerror(errno)); -+ flow_ret = GST_FLOW_ERROR; -+ goto out; -+ } -+ if (FD_ISSET(sink->fd, &fds)) { -+ drmHandleEvent(sink->fd, &evctx); -+ } -+ } -+ -+ display_bufs_queue (sink, buf); -+ -+out: -+ GST_INFO_OBJECT (sink, "exit"); -+ if (buf != inbuf) -+ gst_buffer_unref (buf); -+ g_mutex_unlock (&sink->render_lock); -+ return flow_ret; -+ -+add_fb2_failed: -+ GST_ELEMENT_ERROR (sink, RESOURCE, FAILED, -+ (NULL), ("drmModeAddFB2 failed: %s (%d)", strerror (errno), errno)); -+ flow_ret = GST_FLOW_ERROR; -+ goto out; -+ -+set_plane_failed: -+ GST_ELEMENT_ERROR (sink, RESOURCE, FAILED, -+ (NULL), ("drmModeSetPlane failed: %s (%d)", strerror (errno), errno)); -+ flow_ret = GST_FLOW_ERROR; -+ goto out; -+ -+connector_not_found: -+ GST_ELEMENT_ERROR (sink, RESOURCE, NOT_FOUND, -+ (NULL), ("connector not found", strerror (errno), errno)); -+ goto out; -+} -+ -+ -+static gboolean -+gst_kms_sink_event (GstBaseSink * bsink, GstEvent * event) -+{ -+ GstKMSSink *sink = GST_KMS_SINK (bsink); -+ -+ switch (GST_EVENT_TYPE (event)) { -+ default: -+ break; -+ } -+ if (GST_BASE_SINK_CLASS (gst_kms_sink_parent_class)->event) -+ return GST_BASE_SINK_CLASS (gst_kms_sink_parent_class)->event (bsink, -+ event); -+ else -+ return TRUE; -+} -+ -+static void -+gst_kms_sink_set_property (GObject * object, guint prop_id, -+ const GValue * value, GParamSpec * pspec) -+{ -+ GstKMSSink *sink; -+ -+ g_return_if_fail (GST_IS_KMS_SINK (object)); -+ -+ sink = GST_KMS_SINK (object); -+ -+ switch (prop_id) { -+ case PROP_FORCE_ASPECT_RATIO: -+ sink->keep_aspect = g_value_get_boolean (value); -+ break; -+ case PROP_SCALE: -+ sink->scale = g_value_get_boolean (value); -+ break; -+ case PROP_CONNECTOR: -+ sink->conn_id = g_value_get_uint (value); -+ break; -+ case PROP_CONNECTOR_NAME: -+ g_free (sink->conn_name); -+ sink->conn_name = g_strdup (g_value_get_string (value)); -+ break; -+ case PROP_PIXEL_ASPECT_RATIO: -+ { -+ GValue *tmp; -+ -+ tmp = g_new0 (GValue, 1); -+ g_value_init (tmp, GST_TYPE_FRACTION); -+ -+ if (!g_value_transform (value, tmp)) { -+ GST_WARNING_OBJECT (sink, "Could not transform string to aspect ratio"); -+ } else { -+ sink->par_n = gst_value_get_fraction_numerator (tmp); -+ sink->par_d = gst_value_get_fraction_denominator (tmp); -+ GST_DEBUG_OBJECT (sink, "set PAR to %d/%d", sink->par_n, sink->par_d); -+ } -+ g_free (tmp); -+ } -+ break; -+ default: -+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); -+ break; -+ } -+} -+ -+static void -+gst_kms_sink_get_property (GObject * object, guint prop_id, -+ GValue * value, GParamSpec * pspec) -+{ -+ GstKMSSink *sink; -+ -+ g_return_if_fail (GST_IS_KMS_SINK (object)); -+ -+ sink = GST_KMS_SINK (object); -+ -+ switch (prop_id) { -+ case PROP_FORCE_ASPECT_RATIO: -+ g_value_set_boolean (value, sink->keep_aspect); -+ break; -+ case PROP_SCALE: -+ g_value_set_boolean (value, sink->scale); -+ break; -+ case PROP_CONNECTOR: -+ g_value_set_uint (value, sink->conn.id); -+ break; -+ case PROP_PIXEL_ASPECT_RATIO: -+ { -+ char *v = g_strdup_printf ("%d/%d", sink->par_n, sink->par_d); -+ g_value_take_string (value, v); -+ break; -+ } -+ default: -+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); -+ break; -+ } -+} -+ -+static void -+gst_kms_sink_reset (GstKMSSink * sink) -+{ -+ GST_DEBUG_OBJECT (sink, "reset"); -+ -+ if (sink->fd != -1) { -+ gst_drm_connector_cleanup (sink->fd, &sink->conn); -+ } -+ memset (&sink->conn, 0, sizeof (struct connector)); -+ -+ display_bufs_free (sink); -+ -+ if (sink->pool) { -+ gst_buffer_pool_set_active (GST_BUFFER_POOL(sink->pool), FALSE); -+ gst_object_unref(sink->pool); -+ sink->pool = NULL; -+ } -+ -+ if (sink->plane_resources) { -+ drmModeFreePlaneResources (sink->plane_resources); -+ sink->plane_resources = NULL; -+ } -+ -+ if (sink->resources) { -+ drmModeFreeResources (sink->resources); -+ sink->resources = NULL; -+ } -+ -+ sink->par_n = sink->par_d = 1; -+ sink->src_rect.x = 0; -+ sink->src_rect.y = 0; -+ sink->src_rect.w = 0; -+ sink->src_rect.h = 0; -+ sink->input_width = 0; -+ sink->input_height = 0; -+ sink->format = GST_VIDEO_FORMAT_UNKNOWN; -+ -+ memset (&sink->src_rect, 0, sizeof (GstVideoRectangle)); -+ memset (&sink->dst_rect, 0, sizeof (GstVideoRectangle)); -+} -+ -+static gboolean -+gst_kms_sink_start (GstBaseSink * bsink) -+{ -+ GstKMSSink *sink; -+ -+ sink = GST_KMS_SINK (bsink); -+ -+ drm_dev = dce_init (); -+ if (drm_dev == NULL) -+ goto device_failed; -+ else { -+ sink->dev = drm_dev; -+ sink->fd = dce_get_fd (); -+ drm_fd = dce_get_fd (); -+ } -+ -+ sink->resources = drmModeGetResources (sink->fd); -+ if (sink->resources == NULL) -+ goto resources_failed; -+ -+ sink->plane_resources = drmModeGetPlaneResources (sink->fd); -+ if (sink->plane_resources == NULL) -+ goto plane_resources_failed; -+ -+ return TRUE; -+ -+fail: -+ gst_kms_sink_reset (sink); -+ return FALSE; -+ -+device_failed: -+ GST_ELEMENT_ERROR (sink, RESOURCE, FAILED, -+ (NULL), ("omap_device_new failed")); -+ goto fail; -+ -+resources_failed: -+ GST_ELEMENT_ERROR (sink, RESOURCE, FAILED, -+ (NULL), ("drmModeGetResources failed: %s (%d)", strerror (errno), errno)); -+ goto fail; -+ -+plane_resources_failed: -+ GST_ELEMENT_ERROR (sink, RESOURCE, FAILED, -+ (NULL), ("drmModeGetPlaneResources failed: %s (%d)", -+ strerror (errno), errno)); -+ goto fail; -+} -+ -+static gboolean -+gst_kms_sink_stop (GstBaseSink * bsink) -+{ -+ GstKMSSink *sink; -+ -+ sink = GST_KMS_SINK (bsink); -+ gst_kms_sink_reset (sink); -+ -+ return TRUE; -+} -+ -+ -+static gboolean -+gst_kms_sink_propose_allocation (GstBaseSink * bsink, GstQuery * query) -+{ -+ GstKMSSink *sink; -+ GstStructure *conf; -+ GstCaps *caps; -+ guint size; -+ gboolean need_pool; -+ GstStructure *s; -+ int num_buffers = 0; -+ -+ -+ sink = GST_KMS_SINK (bsink); -+ -+ GST_DEBUG_OBJECT (sink, "begin"); -+ -+ gst_query_parse_allocation (query, &caps, &need_pool); -+ -+ if (G_UNLIKELY (!caps)) { -+ GST_WARNING_OBJECT (sink, "have no caps, doing fallback allocation"); -+ return FALSE; -+ } -+ -+ if (need_pool) { -+ GstVideoInfo info; -+ -+ if (!gst_video_info_from_caps (&info, caps)) -+ goto invalid_caps; -+ -+ GST_LOG_OBJECT (sink, -+ "a bufferpool was requested with caps %" GST_PTR_FORMAT, caps); -+ -+ /* We already have a pool after set_caps */ -+ if (sink->pool) { -+ GstStructure *config; -+ int min,max; -+ config = gst_buffer_pool_get_config (sink->pool); -+ gst_buffer_pool_config_get_params (config, NULL, &size, &min, &max); -+ gst_structure_free (config); -+ -+ gst_query_add_allocation_pool (query, sink->pool, size, min, max); -+ gst_query_add_allocation_param (query, gst_drm_allocator_get (), NULL); -+ return TRUE; -+ } else { -+ GST_LOG_OBJECT (sink, "No bufferpool available"); -+ return FALSE; -+ } -+ } -+ -+ -+invalid_caps: -+ GST_DEBUG_OBJECT (sink, "invalid caps specified"); -+ return FALSE; -+} -+ -+static void -+gst_kms_sink_finalize (GObject * object) -+{ -+ GstKMSSink *sink; -+ -+ sink = GST_KMS_SINK (object); -+ g_mutex_clear (&sink->render_lock); -+ g_free (sink->conn_name); -+ if (sink->kmsbufferpriv){ -+ g_hash_table_destroy (sink->kmsbufferpriv); -+ sink->kmsbufferpriv = NULL; -+ gst_kms_sink_reset (sink); -+} -+ -+ G_OBJECT_CLASS (gst_kms_sink_parent_class)->finalize (object); -+} -+ -+static void -+kmsbufferpriv_free_func (GstKMSBufferPriv *priv) -+{ -+ drmModeRmFB (priv->fd, priv->fb_id); -+ omap_bo_del (priv->bo); -+ g_free(priv); -+} -+ -+ -+static void -+gst_kms_sink_init (GstKMSSink * sink) -+{ -+ sink->fd = -1; -+ gst_kms_sink_reset (sink); -+ sink->kmsbufferpriv = g_hash_table_new_full (g_direct_hash, g_direct_equal, -+ NULL, (GDestroyNotify) kmsbufferpriv_free_func); -+ g_mutex_init (&sink->render_lock); -+} -+ -+static void -+gst_kms_sink_class_init (GstKMSSinkClass * 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; -+ -+ gobject_class->finalize = gst_kms_sink_finalize; -+ gobject_class->set_property = gst_kms_sink_set_property; -+ gobject_class->get_property = gst_kms_sink_get_property; -+ -+ g_object_class_install_property (gobject_class, PROP_FORCE_ASPECT_RATIO, -+ g_param_spec_boolean ("force-aspect-ratio", "Force aspect ratio", -+ "When enabled, reverse caps negotiation (scaling) will respect " -+ "original aspect ratio", 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_SCALE, -+ g_param_spec_boolean ("scale", "Scale", -+ "When true, scale to render fullscreen", FALSE, -+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); -+ g_object_class_install_property (gobject_class, PROP_CONNECTOR, -+ g_param_spec_uint ("connector", "Connector", -+ "DRM connector id (0 for automatic selection)", 0, G_MAXUINT32, 0, -+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT)); -+ g_object_class_install_property (gobject_class, PROP_CONNECTOR_NAME, -+ g_param_spec_string ("connector-name", "Connector name", -+ "DRM connector name (alternative to the connector property, " -+ "use $type$index, $type-$index, or $type)", "", -+ G_PARAM_WRITABLE | G_PARAM_STATIC_STRINGS)); -+ -+ gst_element_class_set_details_simple (gstelement_class, -+ "Video sink", "Sink/Video", -+ "A video sink using the linux kernel mode setting API", -+ "Alessandro Decina "); -+ -+ gst_element_class_add_pad_template (gstelement_class, -+ gst_static_pad_template_get (&gst_kms_sink_template_factory)); -+ -+ gstbasesink_class->set_caps = GST_DEBUG_FUNCPTR (gst_kms_sink_setcaps); -+ gstbasesink_class->get_times = GST_DEBUG_FUNCPTR (gst_kms_sink_get_times); -+ gstbasesink_class->event = GST_DEBUG_FUNCPTR (gst_kms_sink_event); -+ gstbasesink_class->start = GST_DEBUG_FUNCPTR (gst_kms_sink_start); -+ gstbasesink_class->stop = GST_DEBUG_FUNCPTR (gst_kms_sink_stop); -+ gstbasesink_class->propose_allocation = GST_DEBUG_FUNCPTR (gst_kms_sink_propose_allocation); -+ -+ /* disable preroll as it's called before GST_CROP_EVENT has been received, so -+ * we end up configuring the wrong mode... (based on padded caps) -+ */ -+ gstbasesink_class->preroll = NULL; -+ videosink_class->show_frame = GST_DEBUG_FUNCPTR (gst_kms_sink_show_frame); -+} -+ -+static gboolean -+plugin_init (GstPlugin * plugin) -+{ -+ if (!gst_element_register (plugin, "kmssink", -+ GST_RANK_PRIMARY + 1, GST_TYPE_KMS_SINK)) -+ return FALSE; -+ -+ GST_DEBUG_CATEGORY_INIT (gst_debug_kms_sink, "kmssink", 0, "kmssink element"); -+ -+ return TRUE; -+} -+ -+GST_PLUGIN_DEFINE (GST_VERSION_MAJOR, -+ GST_VERSION_MINOR, -+ kms, -+ "KMS video output element", -+ plugin_init, VERSION, GST_LICENSE, GST_PACKAGE_NAME, GST_PACKAGE_ORIGIN) -diff --git a/sys/kms/gstkmssink.h b/sys/kms/gstkmssink.h -new file mode 100644 -index 0000000..9f76839 ---- /dev/null -+++ b/sys/kms/gstkmssink.h -@@ -0,0 +1,92 @@ -+/* GStreamer -+ * -+ * Copyright (C) 2012 Texas Instruments -+ * Copyright (C) 2012 Collabora Ltd -+ * -+ * Authors: -+ * Alessandro Decina -+ * -+ * This library is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU Library General Public -+ * License as published by the Free Software Foundation; either -+ * version 2 of the License, or (at your option) any later version. -+ * -+ * This library is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * Library General Public License for more details. -+ * -+ * You should have received a copy of the GNU Library General Public -+ * License along with this library; if not, write to the -+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330, -+ * Boston, MA 02111-1307, USA. -+ */ -+ -+#ifndef __GST_KMS_SINK_H__ -+#define __GST_KMS_SINK_H__ -+ -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "gstdrmutils.h" -+ -+G_BEGIN_DECLS -+#define GST_TYPE_KMS_SINK \ -+ (gst_kms_sink_get_type()) -+#define GST_KMS_SINK(obj) \ -+ (G_TYPE_CHECK_INSTANCE_CAST((obj), GST_TYPE_KMS_SINK, GstKMSSink)) -+#define GST_KMS_SINK_CLASS(klass) \ -+ (G_TYPE_CHECK_CLASS_CAST((klass), GST_TYPE_KMS_SINK, GstKMSSinkClass)) -+#define GST_IS_KMS_SINK(obj) \ -+ (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_TYPE_KMS_SINK)) -+#define GST_IS_KMS_SINK_CLASS(klass) \ -+ (G_TYPE_CHECK_CLASS_TYPE((klass), GST_TYPE_KMS_SINK)) -+typedef struct _GstKMSSink GstKMSSink; -+typedef struct _GstKMSSinkClass GstKMSSinkClass; -+ -+#define NUM_DISPLAY_BUFS 1 -+ -+struct _GstKMSSink -+{ -+ GstVideoSink videosink; -+ gint input_width, input_height; -+ GstVideoFormat format; -+ gint par_n, par_d; -+ gint fps_n, fps_d; -+ gboolean keep_aspect; -+ GstVideoRectangle src_rect; -+ GstVideoRectangle dst_rect; -+ int fd; -+ struct omap_device *dev; -+ drmModeRes *resources; -+ drmModePlaneRes *plane_resources; -+ struct connector conn; -+ uint32_t conn_id; -+ char *conn_name; -+ drmModePlane *plane; -+ GstBufferPool *pool; -+ GHashTable *kmsbufferpriv; -+ /* current displayed buffer and last displayed buffer: */ -+ GstBuffer *display_bufs[NUM_DISPLAY_BUFS]; -+ gboolean scale; -+ GMutex render_lock; -+}; -+ -+struct _GstKMSSinkClass -+{ -+ GstVideoSinkClass parent_class; -+}; -+ -+GType gst_kms_sink_get_type (void); -+ -+G_END_DECLS -+#endif /* __GST_KMS_SINK_H__ */ --- -1.9.1 - -- cgit 1.2.3-korg