mirror of
git://nv-tegra.nvidia.com/tegra/gst-src/gst-egl.git
synced 2025-12-22 09:21:31 +03:00
Updating prebuilts and/or headers
f29a8e1083e2fe546c68761a196b6dfd5aed14f6 - gstegl_src/gst-egl/Makefile f43858ce2d2f71d6de58ca59ff794fb026689a70 - gstegl_src/gst-egl/LICENSE.libgstnveglglessink 1a0c41a27bfc4e15f352ceaf07a5c88dfc1924bf - gstegl_src/gst-egl/gst-libs/gst/egl/egl.c b8b167b1729c6e6d1341d9bc61689af8b1dd5064 - gstegl_src/gst-egl/gst-libs/gst/egl/egl.h 34174463c5aa7f9b7f84878cff2f38e41cce28ac - gstegl_src/gst-egl/gst-libs/gst/egl/LICENSE.libgstnvegl-1.0 9a83abc5044d31ea41387ac916231ec396665c34 - gstegl_src/gst-egl/pre-gen-source_64/config.h a420f8c656140307d3d3c614228f609b59583c05 - gstegl_src/gst-egl/ext/eglgles/gstegljitter.c a341ac6c564356940984817c53ad37a8af5ae471 - gstegl_src/gst-egl/ext/eglgles/gstegladaptation.h 702531a3023833fbf940b9d8ab568b7bda1d96a7 - gstegl_src/gst-egl/ext/eglgles/gstegladaptation_egl.c ba144260ea5c0b76692d05b4b062c1656293fba3 - gstegl_src/gst-egl/ext/eglgles/gstegljitter.h 8149c234efce25ef230ab00a9d6ba141678575c9 - gstegl_src/gst-egl/ext/eglgles/video_platform_wrapper.h 948247d93a3b7bd800d3601ce6648cd508792054 - gstegl_src/gst-egl/ext/eglgles/gsteglglessink.h 80aab315fad96b237fea7b282e365b90e5185c7f - gstegl_src/gst-egl/ext/eglgles/gsteglglessink.c d2f766addf49a14de24d217ca94c2698410b61c7 - gstegl_src/gst-egl/ext/eglgles/video_platform_wrapper.c 08e9b3d774d0a93abf96dd711ce8d1c412af6373 - gstegl_src/gst-egl/ext/eglgles/gstegladaptation.c Change-Id: Ib5f36e4ce96b608d26e35c6e83312b6cf9d9eefc
This commit is contained in:
17
commitFile.txt
Normal file
17
commitFile.txt
Normal file
@@ -0,0 +1,17 @@
|
||||
Updating prebuilts and/or headers
|
||||
|
||||
f29a8e1083e2fe546c68761a196b6dfd5aed14f6 - gstegl_src/gst-egl/Makefile
|
||||
f43858ce2d2f71d6de58ca59ff794fb026689a70 - gstegl_src/gst-egl/LICENSE.libgstnveglglessink
|
||||
1a0c41a27bfc4e15f352ceaf07a5c88dfc1924bf - gstegl_src/gst-egl/gst-libs/gst/egl/egl.c
|
||||
b8b167b1729c6e6d1341d9bc61689af8b1dd5064 - gstegl_src/gst-egl/gst-libs/gst/egl/egl.h
|
||||
34174463c5aa7f9b7f84878cff2f38e41cce28ac - gstegl_src/gst-egl/gst-libs/gst/egl/LICENSE.libgstnvegl-1.0
|
||||
9a83abc5044d31ea41387ac916231ec396665c34 - gstegl_src/gst-egl/pre-gen-source_64/config.h
|
||||
a420f8c656140307d3d3c614228f609b59583c05 - gstegl_src/gst-egl/ext/eglgles/gstegljitter.c
|
||||
a341ac6c564356940984817c53ad37a8af5ae471 - gstegl_src/gst-egl/ext/eglgles/gstegladaptation.h
|
||||
702531a3023833fbf940b9d8ab568b7bda1d96a7 - gstegl_src/gst-egl/ext/eglgles/gstegladaptation_egl.c
|
||||
ba144260ea5c0b76692d05b4b062c1656293fba3 - gstegl_src/gst-egl/ext/eglgles/gstegljitter.h
|
||||
8149c234efce25ef230ab00a9d6ba141678575c9 - gstegl_src/gst-egl/ext/eglgles/video_platform_wrapper.h
|
||||
948247d93a3b7bd800d3601ce6648cd508792054 - gstegl_src/gst-egl/ext/eglgles/gsteglglessink.h
|
||||
80aab315fad96b237fea7b282e365b90e5185c7f - gstegl_src/gst-egl/ext/eglgles/gsteglglessink.c
|
||||
d2f766addf49a14de24d217ca94c2698410b61c7 - gstegl_src/gst-egl/ext/eglgles/video_platform_wrapper.c
|
||||
08e9b3d774d0a93abf96dd711ce8d1c412af6373 - gstegl_src/gst-egl/ext/eglgles/gstegladaptation.c
|
||||
43
gstegl_src/README.txt
Normal file
43
gstegl_src/README.txt
Normal file
@@ -0,0 +1,43 @@
|
||||
This package contains the code for libgstnvegl-1.0.so library
|
||||
|
||||
DEPENDENCIES:
|
||||
------------
|
||||
(1) EGL
|
||||
(2) OPENGLES2
|
||||
(3) Gstreamer >= 1.2.3
|
||||
(4) X11, Xext
|
||||
|
||||
The above target machine dependencies can be obtained from any standard
|
||||
distribution (like https://launchpad.net/ubuntu) or can be self-built.
|
||||
|
||||
Above required packages can also be installed using the following command:
|
||||
|
||||
sudo apt-get install \
|
||||
autoconf \
|
||||
automake \
|
||||
autopoint \
|
||||
autotools-dev \
|
||||
gtk-doc-tools \
|
||||
libegl1-mesa-dev \
|
||||
libgles2-mesa-dev \
|
||||
libgstreamer1.0-dev \
|
||||
libgstreamer-plugins-base1.0-dev \
|
||||
libgtk2.0-dev \
|
||||
libtool \
|
||||
libx11-dev \
|
||||
libxext-dev \
|
||||
pkg-config
|
||||
|
||||
This package was built against the (above) libs present in Ubuntu 16.04.
|
||||
|
||||
INSTALLATION:
|
||||
-------------
|
||||
1) Untar the package and enter the dir
|
||||
2) ./autogen.sh
|
||||
3) ./configure
|
||||
4) make
|
||||
5) sudo make install
|
||||
|
||||
Note:
|
||||
Pass the appropriate flags and toolchain path to "configure" for tha ARM build.
|
||||
|
||||
41
gstegl_src/gst-egl/BUILD.txt
Normal file
41
gstegl_src/gst-egl/BUILD.txt
Normal file
@@ -0,0 +1,41 @@
|
||||
###############################################################################
|
||||
#
|
||||
# Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved.
|
||||
#
|
||||
# NVIDIA Corporation and its licensors retain all intellectual property
|
||||
# and proprietary rights in and to this software, related documentation
|
||||
# and any modifications thereto. Any use, reproduction, disclosure or
|
||||
# distribution of this software and related documentation without an express
|
||||
# license agreement from NVIDIA Corporation is strictly prohibited.
|
||||
#
|
||||
###############################################################################
|
||||
|
||||
Steps to compile the "gst-nveglglessink" sources:
|
||||
|
||||
1) Install gstreamer related packages using the command:
|
||||
|
||||
sudo apt-get install gstreamer1.0-tools gstreamer1.0-alsa \
|
||||
gstreamer1.0-plugins-base gstreamer1.0-plugins-good \
|
||||
gstreamer1.0-plugins-bad gstreamer1.0-plugins-ugly \
|
||||
gstreamer1.0-libav libgstreamer1.0-dev \
|
||||
libgstreamer-plugins-base1.0-dev libegl1-mesa-dev
|
||||
|
||||
2) Install wayland related packages if not present:
|
||||
sudo apt-get install libwayland-dev
|
||||
|
||||
3) Install CUDA Runtime 10.0+
|
||||
|
||||
4) Install Deepstream 6.0
|
||||
|
||||
5) Extract the package "gstegl_src.tbz2" as follow:
|
||||
|
||||
tar xvjf gstegl_src.tbz2`
|
||||
|
||||
6) cd "gstegl_src/gst_egl/"
|
||||
|
||||
7) Export the appropriate CUDA_VER using - "export CUDA_VER=<cuda-version>"
|
||||
|
||||
8) run "make" to create "libgstnveglglessink.so"
|
||||
|
||||
9) run "sudo make install" to install "libgstnveglglessink.so" in
|
||||
"/usr/lib/aarch64-linux-gnu/gstreamer-1.0".
|
||||
24
gstegl_src/gst-egl/LICENSE.libgstnveglglessink
Normal file
24
gstegl_src/gst-egl/LICENSE.libgstnveglglessink
Normal file
@@ -0,0 +1,24 @@
|
||||
GStreamer EGL/GLES Sink
|
||||
Copyright (C) 2012 Collabora Ltd.
|
||||
@author: Reynaldo H. Verdejo Pinochet <reynaldo@collabora.com>
|
||||
@author: Sebastian Dröge <sebastian.droege@collabora.co.uk>
|
||||
|
||||
Copyright (c) 2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
to deal in the Software without restriction, including without limitation
|
||||
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
and/or sell copies of the Software, and to permit persons to whom the
|
||||
Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
74
gstegl_src/gst-egl/Makefile
Normal file
74
gstegl_src/gst-egl/Makefile
Normal file
@@ -0,0 +1,74 @@
|
||||
###############################################################################
|
||||
#
|
||||
# Copyright (c) 2022-2023, NVIDIA CORPORATION. All rights reserved.
|
||||
#
|
||||
# NVIDIA Corporation and its licensors retain all intellectual property
|
||||
# and proprietary rights in and to this software, related documentation
|
||||
# and any modifications thereto. Any use, reproduction, disclosure or
|
||||
# distribution of this software and related documentation without an express
|
||||
# license agreement from NVIDIA Corporation is strictly prohibited.
|
||||
#
|
||||
###############################################################################
|
||||
|
||||
ifneq ($(MAKECMDGOALS),install)
|
||||
ifeq ($(CUDA_VER),)
|
||||
$(error "CUDA_VER is not set. Set it by running - "export CUDA_VER=<cuda-version>"")
|
||||
endif
|
||||
endif
|
||||
|
||||
SO_NAME := libgstnveglglessink.so
|
||||
DEST_DIR ?= /usr/lib/aarch64-linux-gnu/gstreamer-1.0
|
||||
|
||||
SRCS := ext/eglgles/gstegladaptation.c \
|
||||
ext/eglgles/gstegladaptation_egl.c \
|
||||
ext/eglgles/gsteglglessink.c \
|
||||
ext/eglgles/gstegljitter.c \
|
||||
ext/eglgles/video_platform_wrapper.c \
|
||||
gst-libs/gst/egl/egl.c
|
||||
|
||||
INCLUDES += -I./pre-gen-source_64/ \
|
||||
-I./gst-libs \
|
||||
-I./gst-libs/gst/egl \
|
||||
-I/opt/nvidia/deepstream/deepstream-6.0/sources/includes/ \
|
||||
-I/usr/local/include/gstreamer-1.0 \
|
||||
-I/usr/local/cuda-$(CUDA_VER)/targets/aarch64-linux/include/ \
|
||||
-I./
|
||||
|
||||
PKGS := glib-2.0 \
|
||||
gstreamer-1.0 \
|
||||
gstreamer-base-1.0 \
|
||||
gstreamer-video-1.0
|
||||
|
||||
OBJS := $(SRCS:.c=.o)
|
||||
|
||||
CFLAGS := -fPIC \
|
||||
-DHAVE_CONFIG_H \
|
||||
-DG_THREADS_MANDATORY \
|
||||
-DG_DISABLE_DEPRECATED \
|
||||
-DUSE_EGL_TEGRA \
|
||||
-DUSE_EGL_WAYLAND
|
||||
|
||||
CFLAGS += `pkg-config --cflags $(PKGS)`
|
||||
|
||||
LDFLAGS = -Wl,--no-undefined -L/usr/lib/aarch64-linux-gnu/tegra -L/usr/local/cuda-$(CUDA_VER)/targets/aarch64-linux/lib/
|
||||
|
||||
LIBS = -lnvbufsurface -lGLESv2 -lEGL -lX11 -lm -lcuda -lcudart -lwayland-client -lwayland-egl
|
||||
|
||||
LIBS += `pkg-config --libs $(PKGS)`
|
||||
|
||||
all: $(SO_NAME)
|
||||
|
||||
%.o: %.c
|
||||
$(CC) -c $< $(CFLAGS) $(INCLUDES) -o $@
|
||||
|
||||
$(SO_NAME): $(OBJS)
|
||||
$(CC) -shared -o $(SO_NAME) $(OBJS) $(LIBS) $(LDFLAGS)
|
||||
|
||||
.PHONY: install
|
||||
install: $(SO_NAME)
|
||||
cp -vp $(SO_NAME) $(DEST_DIR)
|
||||
|
||||
.PHONY: clean
|
||||
clean:
|
||||
rm -rf $(OBJS) $(SO_NAME)
|
||||
|
||||
41
gstegl_src/gst-egl/chooseNvcfgProfile.mk
Normal file
41
gstegl_src/gst-egl/chooseNvcfgProfile.mk
Normal file
@@ -0,0 +1,41 @@
|
||||
# Copyright (c) 2020, NVIDIA CORPORATION. All Rights Reserved.
|
||||
#
|
||||
# NVIDIA Corporation and its licensors retain all intellectual property and
|
||||
# proprietary rights in and to this software and related documentation. Any
|
||||
# use, reproduction, disclosure or distribution of this software and related
|
||||
# documentation without an express license agreement from NVIDIA Corporation
|
||||
# is strictly prohibited.
|
||||
#
|
||||
# Source for this file: $(TEGRA_TOP)/tmake/artifacts/CommonRulesNvMake.tmk
|
||||
|
||||
ifeq ($(NV_BUILD_CONFIGURATION_LINUX_USERSPACE_IS_EMBEDDED),1)
|
||||
ifeq ($(NV_BUILD_CONFIGURATION_IS_EXTERNAL),0)
|
||||
NVCFG_PROFILE=tegragpu_unix_arm_embedded_profile
|
||||
else ifeq ($(NV_BUILD_CONFIGURATION_IS_GNEXT),1)
|
||||
NVCFG_PROFILE=tegragpu_unix_arm_embedded_gnext_profile
|
||||
else
|
||||
NVCFG_PROFILE=tegragpu_unix_arm_embedded_external_profile
|
||||
endif
|
||||
else ifeq ($(NV_BUILD_CONFIGURATION_LINUX_USERSPACE_IS_L4T),1)
|
||||
ifneq ($(NV_BUILD_CONFIGURATION_IS_EXTERNAL),0)
|
||||
ifeq ($(NV_BUILD_CONFIGURATION_IS_GNEXT),1)
|
||||
NVCFG_PROFILE=l4t_global_gnext_profile
|
||||
else
|
||||
NVCFG_PROFILE=l4t_global_external_profile
|
||||
endif
|
||||
else
|
||||
NVCFG_PROFILE=tegragpu_unix_arm_global_profile
|
||||
endif
|
||||
else ifeq ($(NV_BUILD_CONFIGURATION_OS_IS_QNX),1)
|
||||
ifeq ($(NV_BUILD_CONFIGURATION_IS_EXTERNAL),0)
|
||||
NVCFG_PROFILE=tegragpu_unix_arm_embedded_profile
|
||||
else ifeq ($(NV_BUILD_CONFIGURATION_IS_GNEXT),1)
|
||||
NVCFG_PROFILE=tegragpu_unix_arm_embedded_gnext_profile
|
||||
else ifeq ($(NV_BUILD_CONFIGURATION_IS_SAFETY),1)
|
||||
NVCFG_PROFILE=tegra_with_dgpu_embedded_safety_external_profile
|
||||
else
|
||||
NVCFG_PROFILE=tegragpu_unix_arm_embedded_external_profile
|
||||
endif
|
||||
else
|
||||
$(error Unsupported OS)
|
||||
endif
|
||||
716
gstegl_src/gst-egl/ext/eglgles/gstegladaptation.c
Normal file
716
gstegl_src/gst-egl/ext/eglgles/gstegladaptation.c
Normal file
@@ -0,0 +1,716 @@
|
||||
/*
|
||||
* GStreamer EGL/GLES Sink Adaptation
|
||||
* Copyright (C) 2012-2013 Collabora Ltd.
|
||||
* @author: Reynaldo H. Verdejo Pinochet <reynaldo@collabora.com>
|
||||
* @author: Sebastian Dröge <sebastian.droege@collabora.co.uk>
|
||||
* @author: Thiago Santos <thiago.sousa.santos@collabora.com>
|
||||
* Copyright (c) 2015, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "gstegladaptation.h"
|
||||
|
||||
#include <gst/video/video.h>
|
||||
#include <string.h>
|
||||
|
||||
#define GST_CAT_DEFAULT egladaption_debug
|
||||
GST_DEBUG_CATEGORY (egladaption_debug);
|
||||
|
||||
/* GLESv2 GLSL Shaders
|
||||
*
|
||||
* OpenGL ES Standard does not mandate YUV support. This is
|
||||
* why most of these shaders deal with Packed/Planar YUV->RGB
|
||||
* conversion.
|
||||
*/
|
||||
|
||||
/* *INDENT-OFF* */
|
||||
/* Direct vertex copy */
|
||||
static const char *vert_COPY_prog = {
|
||||
"attribute vec3 position;"
|
||||
"attribute vec2 texpos;"
|
||||
"varying vec2 opos;"
|
||||
"void main(void)"
|
||||
"{"
|
||||
" opos = texpos;"
|
||||
" gl_Position = vec4(position, 1.0);"
|
||||
"}"
|
||||
};
|
||||
|
||||
static const char *vert_COPY_prog_no_tex = {
|
||||
"attribute vec3 position;"
|
||||
"void main(void)"
|
||||
"{"
|
||||
" gl_Position = vec4(position, 1.0);"
|
||||
"}"
|
||||
};
|
||||
|
||||
/* Paint all black */
|
||||
static const char *frag_BLACK_prog = {
|
||||
"precision mediump float;"
|
||||
"void main(void)"
|
||||
"{"
|
||||
" gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0);"
|
||||
"}"
|
||||
};
|
||||
|
||||
/* Direct fragments copy with stride-scaling */
|
||||
static const char *frag_COPY_prog = {
|
||||
"precision mediump float;"
|
||||
"varying vec2 opos;"
|
||||
"uniform sampler2D tex;"
|
||||
"uniform vec2 tex_scale0;"
|
||||
"uniform vec2 tex_scale1;"
|
||||
"uniform vec2 tex_scale2;"
|
||||
"void main(void)"
|
||||
"{"
|
||||
" vec4 t = texture2D(tex, opos / tex_scale0);"
|
||||
" gl_FragColor = vec4(t.rgb, 1.0);"
|
||||
"}"
|
||||
};
|
||||
|
||||
/* Channel reordering for XYZ <-> ZYX conversion */
|
||||
static const char *frag_REORDER_prog = {
|
||||
"precision mediump float;"
|
||||
"varying vec2 opos;"
|
||||
"uniform sampler2D tex;"
|
||||
"uniform vec2 tex_scale0;"
|
||||
"uniform vec2 tex_scale1;"
|
||||
"uniform vec2 tex_scale2;"
|
||||
"void main(void)"
|
||||
"{"
|
||||
" vec4 t = texture2D(tex, opos / tex_scale0);"
|
||||
" gl_FragColor = vec4(t.%c, t.%c, t.%c, 1.0);"
|
||||
"}"
|
||||
};
|
||||
|
||||
/* Packed YUV converters */
|
||||
|
||||
/** AYUV to RGB conversion */
|
||||
static const char *frag_AYUV_prog = {
|
||||
"precision mediump float;"
|
||||
"varying vec2 opos;"
|
||||
"uniform sampler2D tex;"
|
||||
"uniform vec2 tex_scale0;"
|
||||
"uniform vec2 tex_scale1;"
|
||||
"uniform vec2 tex_scale2;"
|
||||
"const vec3 offset = vec3(-0.0625, -0.5, -0.5);"
|
||||
"const vec3 rcoeff = vec3(1.164, 0.000, 1.596);"
|
||||
"const vec3 gcoeff = vec3(1.164,-0.391,-0.813);"
|
||||
"const vec3 bcoeff = vec3(1.164, 2.018, 0.000);"
|
||||
"void main(void) {"
|
||||
" float r,g,b;"
|
||||
" vec3 yuv;"
|
||||
" yuv = texture2D(tex,opos / tex_scale0).gba;"
|
||||
" yuv += offset;"
|
||||
" r = dot(yuv, rcoeff);"
|
||||
" g = dot(yuv, gcoeff);"
|
||||
" b = dot(yuv, bcoeff);"
|
||||
" gl_FragColor=vec4(r,g,b,1.0);"
|
||||
"}"
|
||||
};
|
||||
|
||||
/* Planar YUV converters */
|
||||
|
||||
/** YUV to RGB conversion */
|
||||
static const char *frag_PLANAR_YUV_prog = {
|
||||
"precision mediump float;"
|
||||
"varying vec2 opos;"
|
||||
"uniform sampler2D Ytex,Utex,Vtex;"
|
||||
"uniform vec2 tex_scale0;"
|
||||
"uniform vec2 tex_scale1;"
|
||||
"uniform vec2 tex_scale2;"
|
||||
"const vec3 offset = vec3(-0.0625, -0.5, -0.5);"
|
||||
"const vec3 rcoeff = vec3(1.164, 0.000, 1.596);"
|
||||
"const vec3 gcoeff = vec3(1.164,-0.391,-0.813);"
|
||||
"const vec3 bcoeff = vec3(1.164, 2.018, 0.000);"
|
||||
"void main(void) {"
|
||||
" float r,g,b;"
|
||||
" vec3 yuv;"
|
||||
" yuv.x=texture2D(Ytex,opos / tex_scale0).r;"
|
||||
" yuv.y=texture2D(Utex,opos / tex_scale1).r;"
|
||||
" yuv.z=texture2D(Vtex,opos / tex_scale2).r;"
|
||||
" yuv += offset;"
|
||||
" r = dot(yuv, rcoeff);"
|
||||
" g = dot(yuv, gcoeff);"
|
||||
" b = dot(yuv, bcoeff);"
|
||||
" gl_FragColor=vec4(r,g,b,1.0);"
|
||||
"}"
|
||||
};
|
||||
|
||||
/** NV12/NV21 to RGB conversion */
|
||||
static const char *frag_NV12_NV21_prog = {
|
||||
"precision mediump float;"
|
||||
"varying vec2 opos;"
|
||||
"uniform sampler2D Ytex,UVtex;"
|
||||
"uniform vec2 tex_scale0;"
|
||||
"uniform vec2 tex_scale1;"
|
||||
"uniform vec2 tex_scale2;"
|
||||
"const vec3 offset = vec3(-0.0625, -0.5, -0.5);"
|
||||
"const vec3 rcoeff = vec3(1.164, 0.000, 1.596);"
|
||||
"const vec3 gcoeff = vec3(1.164,-0.391,-0.813);"
|
||||
"const vec3 bcoeff = vec3(1.164, 2.018, 0.000);"
|
||||
"void main(void) {"
|
||||
" float r,g,b;"
|
||||
" vec3 yuv;"
|
||||
" yuv.x=texture2D(Ytex,opos / tex_scale0).r;"
|
||||
" yuv.yz=texture2D(UVtex,opos / tex_scale1).%c%c;"
|
||||
" yuv += offset;"
|
||||
" r = dot(yuv, rcoeff);"
|
||||
" g = dot(yuv, gcoeff);"
|
||||
" b = dot(yuv, bcoeff);"
|
||||
" gl_FragColor=vec4(r,g,b,1.0);"
|
||||
"}"
|
||||
};
|
||||
/* *INDENT-ON* */
|
||||
|
||||
void
|
||||
gst_egl_adaption_init (void)
|
||||
{
|
||||
GST_DEBUG_CATEGORY_INIT (egladaption_debug, "egladaption", 0,
|
||||
"EGL adaption layer");
|
||||
}
|
||||
|
||||
static GstCaps *
|
||||
_gst_video_format_new_template_caps (GstVideoFormat format)
|
||||
{
|
||||
return gst_caps_new_simple ("video/x-raw",
|
||||
"format", G_TYPE_STRING, gst_video_format_to_string (format),
|
||||
"width", GST_TYPE_INT_RANGE, 1, G_MAXINT,
|
||||
"height", GST_TYPE_INT_RANGE, 1, G_MAXINT,
|
||||
"framerate", GST_TYPE_FRACTION_RANGE, 0, 1, G_MAXINT, 1, NULL);
|
||||
}
|
||||
|
||||
GstCaps *
|
||||
gst_egl_adaptation_fill_supported_fbuffer_configs (GstEglAdaptationContext *
|
||||
ctx)
|
||||
{
|
||||
GstCaps *caps = NULL, *copy1, *copy2;
|
||||
guint i, n;
|
||||
|
||||
GST_DEBUG_OBJECT (ctx->element,
|
||||
"Building initial list of wanted eglattribs per format");
|
||||
|
||||
/* Init supported format/caps list */
|
||||
if (_gst_egl_choose_config (ctx, TRUE, NULL)) {
|
||||
|
||||
caps = gst_caps_new_empty ();
|
||||
|
||||
gst_caps_append (caps,
|
||||
_gst_video_format_new_template_caps (GST_VIDEO_FORMAT_RGBA));
|
||||
gst_caps_append (caps,
|
||||
_gst_video_format_new_template_caps (GST_VIDEO_FORMAT_BGRA));
|
||||
gst_caps_append (caps,
|
||||
_gst_video_format_new_template_caps (GST_VIDEO_FORMAT_ARGB));
|
||||
gst_caps_append (caps,
|
||||
_gst_video_format_new_template_caps (GST_VIDEO_FORMAT_ABGR));
|
||||
gst_caps_append (caps,
|
||||
_gst_video_format_new_template_caps (GST_VIDEO_FORMAT_RGBx));
|
||||
gst_caps_append (caps,
|
||||
_gst_video_format_new_template_caps (GST_VIDEO_FORMAT_BGRx));
|
||||
gst_caps_append (caps,
|
||||
_gst_video_format_new_template_caps (GST_VIDEO_FORMAT_xRGB));
|
||||
gst_caps_append (caps,
|
||||
_gst_video_format_new_template_caps (GST_VIDEO_FORMAT_xBGR));
|
||||
gst_caps_append (caps,
|
||||
_gst_video_format_new_template_caps (GST_VIDEO_FORMAT_AYUV));
|
||||
gst_caps_append (caps,
|
||||
_gst_video_format_new_template_caps (GST_VIDEO_FORMAT_Y444));
|
||||
gst_caps_append (caps,
|
||||
_gst_video_format_new_template_caps (GST_VIDEO_FORMAT_RGB));
|
||||
gst_caps_append (caps,
|
||||
_gst_video_format_new_template_caps (GST_VIDEO_FORMAT_BGR));
|
||||
gst_caps_append (caps,
|
||||
_gst_video_format_new_template_caps (GST_VIDEO_FORMAT_I420));
|
||||
gst_caps_append (caps,
|
||||
_gst_video_format_new_template_caps (GST_VIDEO_FORMAT_YV12));
|
||||
gst_caps_append (caps,
|
||||
_gst_video_format_new_template_caps (GST_VIDEO_FORMAT_NV12));
|
||||
gst_caps_append (caps,
|
||||
_gst_video_format_new_template_caps (GST_VIDEO_FORMAT_NV21));
|
||||
gst_caps_append (caps,
|
||||
_gst_video_format_new_template_caps (GST_VIDEO_FORMAT_Y42B));
|
||||
gst_caps_append (caps,
|
||||
_gst_video_format_new_template_caps (GST_VIDEO_FORMAT_Y41B));
|
||||
gst_caps_append (caps,
|
||||
_gst_video_format_new_template_caps (GST_VIDEO_FORMAT_RGB16));
|
||||
|
||||
copy1 = gst_caps_copy (caps);
|
||||
copy2 = gst_caps_copy (caps);
|
||||
|
||||
#ifndef HAVE_IOS
|
||||
n = gst_caps_get_size (caps);
|
||||
for (i = 0; i < n; i++) {
|
||||
GstCapsFeatures *features =
|
||||
gst_caps_features_new (GST_CAPS_FEATURE_MEMORY_EGL_IMAGE, NULL);
|
||||
gst_caps_set_features (caps, i, features);
|
||||
}
|
||||
#endif
|
||||
|
||||
n = gst_caps_get_size (copy1);
|
||||
for (i = 0; i < n; i++) {
|
||||
GstCapsFeatures *features =
|
||||
gst_caps_features_new
|
||||
(GST_CAPS_FEATURE_META_GST_VIDEO_GL_TEXTURE_UPLOAD_META, NULL);
|
||||
gst_caps_set_features (copy1, i, features);
|
||||
}
|
||||
|
||||
gst_caps_append (caps, copy1);
|
||||
gst_caps_append (caps, copy2);
|
||||
|
||||
n = gst_caps_get_size (caps);
|
||||
gst_caps_append (caps,
|
||||
_gst_video_format_new_template_caps (GST_VIDEO_FORMAT_BGRx));
|
||||
gst_caps_append (caps,
|
||||
_gst_video_format_new_template_caps (GST_VIDEO_FORMAT_RGBA));
|
||||
gst_caps_append (caps,
|
||||
_gst_video_format_new_template_caps (GST_VIDEO_FORMAT_I420));
|
||||
gst_caps_append (caps,
|
||||
_gst_video_format_new_template_caps (GST_VIDEO_FORMAT_NV12));
|
||||
gst_caps_append (caps,
|
||||
_gst_video_format_new_template_caps (GST_VIDEO_FORMAT_RGB));
|
||||
gst_caps_append (caps,
|
||||
_gst_video_format_new_template_caps (GST_VIDEO_FORMAT_BGR));
|
||||
for (i = n; i < n+6; i++) {
|
||||
GstCapsFeatures *features =
|
||||
gst_caps_features_new ("memory:NVMM", NULL);
|
||||
gst_caps_set_features (caps, i, features);
|
||||
}
|
||||
|
||||
} else {
|
||||
GST_INFO_OBJECT (ctx->element,
|
||||
"EGL display doesn't support RGBA8888 config");
|
||||
}
|
||||
|
||||
return caps;
|
||||
}
|
||||
|
||||
void
|
||||
gst_egl_adaptation_cleanup (GstEglAdaptationContext * ctx)
|
||||
{
|
||||
gint i;
|
||||
|
||||
if (ctx->have_vbo) {
|
||||
glDeleteBuffers (1, &ctx->position_buffer);
|
||||
glDeleteBuffers (1, &ctx->index_buffer);
|
||||
ctx->have_vbo = FALSE;
|
||||
}
|
||||
|
||||
if (ctx->have_texture) {
|
||||
glDeleteTextures (ctx->n_textures, ctx->texture);
|
||||
ctx->have_texture = FALSE;
|
||||
ctx->n_textures = 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < 2; i++) {
|
||||
if (ctx->glslprogram[i]) {
|
||||
glUseProgram (0);
|
||||
glDetachShader (ctx->glslprogram[i], ctx->fragshader[i]);
|
||||
glDetachShader (ctx->glslprogram[i], ctx->vertshader[i]);
|
||||
glDeleteProgram (ctx->glslprogram[i]);
|
||||
glDeleteShader (ctx->fragshader[i]);
|
||||
glDeleteShader (ctx->vertshader[i]);
|
||||
ctx->glslprogram[i] = 0;
|
||||
ctx->fragshader[i] = 0;
|
||||
ctx->vertshader[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
gst_egl_adaptation_context_make_current (ctx, FALSE);
|
||||
|
||||
gst_egl_adaptation_destroy_surface (ctx);
|
||||
gst_egl_adaptation_destroy_context (ctx);
|
||||
}
|
||||
|
||||
gboolean
|
||||
got_gl_error (const char *wtf)
|
||||
{
|
||||
GLuint error = GL_NO_ERROR;
|
||||
|
||||
if ((error = glGetError ()) != GL_NO_ERROR) {
|
||||
GST_CAT_ERROR (GST_CAT_DEFAULT, "GL ERROR: %s returned 0x%04x", wtf, error);
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
create_shader_program (GstEglAdaptationContext * ctx, GLuint * prog,
|
||||
GLuint * vert, GLuint * frag, const gchar * vert_text,
|
||||
const gchar * frag_text)
|
||||
{
|
||||
GLint test;
|
||||
GLchar *info_log;
|
||||
|
||||
/* Build shader program for video texture rendering */
|
||||
*vert = glCreateShader (GL_VERTEX_SHADER);
|
||||
GST_DEBUG_OBJECT (ctx->element, "Sending %s to handle %d", vert_text, *vert);
|
||||
glShaderSource (*vert, 1, &vert_text, NULL);
|
||||
if (got_gl_error ("glShaderSource vertex"))
|
||||
goto HANDLE_ERROR;
|
||||
|
||||
glCompileShader (*vert);
|
||||
if (got_gl_error ("glCompileShader vertex"))
|
||||
goto HANDLE_ERROR;
|
||||
|
||||
glGetShaderiv (*vert, GL_COMPILE_STATUS, &test);
|
||||
if (test != GL_FALSE)
|
||||
GST_DEBUG_OBJECT (ctx->element, "Successfully compiled vertex shader");
|
||||
else {
|
||||
GST_ERROR_OBJECT (ctx->element, "Couldn't compile vertex shader");
|
||||
glGetShaderiv (*vert, GL_INFO_LOG_LENGTH, &test);
|
||||
info_log = g_new0 (GLchar, test);
|
||||
glGetShaderInfoLog (*vert, test, NULL, info_log);
|
||||
GST_INFO_OBJECT (ctx->element, "Compilation info log:\n%s", info_log);
|
||||
g_free (info_log);
|
||||
goto HANDLE_ERROR;
|
||||
}
|
||||
|
||||
*frag = glCreateShader (GL_FRAGMENT_SHADER);
|
||||
GST_DEBUG_OBJECT (ctx->element, "Sending %s to handle %d", frag_text, *frag);
|
||||
glShaderSource (*frag, 1, &frag_text, NULL);
|
||||
if (got_gl_error ("glShaderSource fragment"))
|
||||
goto HANDLE_ERROR;
|
||||
|
||||
glCompileShader (*frag);
|
||||
if (got_gl_error ("glCompileShader fragment"))
|
||||
goto HANDLE_ERROR;
|
||||
|
||||
glGetShaderiv (*frag, GL_COMPILE_STATUS, &test);
|
||||
if (test != GL_FALSE)
|
||||
GST_DEBUG_OBJECT (ctx->element, "Successfully compiled fragment shader");
|
||||
else {
|
||||
GST_ERROR_OBJECT (ctx->element, "Couldn't compile fragment shader");
|
||||
glGetShaderiv (*frag, GL_INFO_LOG_LENGTH, &test);
|
||||
info_log = g_new0 (GLchar, test);
|
||||
glGetShaderInfoLog (*frag, test, NULL, info_log);
|
||||
GST_INFO_OBJECT (ctx->element, "Compilation info log:\n%s", info_log);
|
||||
g_free (info_log);
|
||||
goto HANDLE_ERROR;
|
||||
}
|
||||
|
||||
*prog = glCreateProgram ();
|
||||
if (got_gl_error ("glCreateProgram"))
|
||||
goto HANDLE_ERROR;
|
||||
glAttachShader (*prog, *vert);
|
||||
if (got_gl_error ("glAttachShader vertices"))
|
||||
goto HANDLE_ERROR;
|
||||
glAttachShader (*prog, *frag);
|
||||
if (got_gl_error ("glAttachShader fragments"))
|
||||
goto HANDLE_ERROR;
|
||||
glLinkProgram (*prog);
|
||||
glGetProgramiv (*prog, GL_LINK_STATUS, &test);
|
||||
if (test != GL_FALSE) {
|
||||
GST_DEBUG_OBJECT (ctx->element, "GLES: Successfully linked program");
|
||||
} else {
|
||||
GST_ERROR_OBJECT (ctx->element, "Couldn't link program");
|
||||
goto HANDLE_ERROR;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
|
||||
HANDLE_ERROR:
|
||||
{
|
||||
if (*frag && *prog)
|
||||
glDetachShader (*prog, *frag);
|
||||
if (*vert && *prog)
|
||||
glDetachShader (*prog, *vert);
|
||||
if (*prog)
|
||||
glDeleteProgram (*prog);
|
||||
if (*frag)
|
||||
glDeleteShader (*frag);
|
||||
if (*vert)
|
||||
glDeleteShader (*vert);
|
||||
*prog = 0;
|
||||
*frag = 0;
|
||||
*vert = 0;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
gboolean
|
||||
gst_egl_adaptation_init_surface (GstEglAdaptationContext * ctx,
|
||||
GstVideoFormat format)
|
||||
{
|
||||
GLboolean ret;
|
||||
const gchar *texnames[3] = { NULL, };
|
||||
gchar *frag_prog = NULL;
|
||||
gboolean free_frag_prog = FALSE;
|
||||
gint i;
|
||||
|
||||
GST_DEBUG_OBJECT (ctx->element, "Enter EGL surface setup");
|
||||
|
||||
if (!gst_egl_adaptation_create_surface (ctx)) {
|
||||
GST_ERROR_OBJECT (ctx->element, "Can't create surface");
|
||||
goto HANDLE_ERROR_LOCKED;
|
||||
}
|
||||
|
||||
if (!gst_egl_adaptation_context_make_current (ctx, TRUE))
|
||||
goto HANDLE_ERROR_LOCKED;
|
||||
|
||||
gst_egl_adaptation_query_buffer_preserved (ctx);
|
||||
|
||||
gst_egl_adaptation_init_exts (ctx);
|
||||
|
||||
/* Save surface dims */
|
||||
gst_egl_adaptation_update_surface_dimensions (ctx);
|
||||
|
||||
/* Save display's pixel aspect ratio
|
||||
*
|
||||
* DAR is reported as w/h * EGL_DISPLAY_SCALING wich is
|
||||
* a constant with value 10000. This attribute is only
|
||||
* supported if the EGL version is >= 1.2
|
||||
* XXX: Setup this as a property.
|
||||
* or some other one time check. Right now it's being called once
|
||||
* per frame.
|
||||
*/
|
||||
gst_egl_adaptation_query_par (ctx);
|
||||
|
||||
/* We have a surface! */
|
||||
ctx->have_surface = TRUE;
|
||||
|
||||
/* Init vertex and fragment GLSL shaders.
|
||||
* Note: Shader compiler support is optional but we currently rely on it.
|
||||
*/
|
||||
|
||||
glGetBooleanv (GL_SHADER_COMPILER, &ret);
|
||||
if (ret == GL_FALSE) {
|
||||
GST_ERROR_OBJECT (ctx->element, "Shader compiler support is unavailable!");
|
||||
goto HANDLE_ERROR;
|
||||
}
|
||||
|
||||
/* Build shader program for video texture rendering */
|
||||
|
||||
switch (format) {
|
||||
case GST_VIDEO_FORMAT_AYUV:
|
||||
frag_prog = (gchar *) frag_AYUV_prog;
|
||||
free_frag_prog = FALSE;
|
||||
ctx->n_textures = 1;
|
||||
texnames[0] = "tex";
|
||||
break;
|
||||
case GST_VIDEO_FORMAT_Y444:
|
||||
case GST_VIDEO_FORMAT_I420:
|
||||
case GST_VIDEO_FORMAT_YV12:
|
||||
case GST_VIDEO_FORMAT_Y42B:
|
||||
case GST_VIDEO_FORMAT_Y41B:
|
||||
frag_prog = (gchar *) frag_PLANAR_YUV_prog;
|
||||
free_frag_prog = FALSE;
|
||||
ctx->n_textures = 3;
|
||||
texnames[0] = "Ytex";
|
||||
texnames[1] = "Utex";
|
||||
texnames[2] = "Vtex";
|
||||
break;
|
||||
case GST_VIDEO_FORMAT_NV12:
|
||||
frag_prog = g_strdup_printf (frag_NV12_NV21_prog, 'r', 'a');
|
||||
free_frag_prog = TRUE;
|
||||
ctx->n_textures = 2;
|
||||
texnames[0] = "Ytex";
|
||||
texnames[1] = "UVtex";
|
||||
break;
|
||||
case GST_VIDEO_FORMAT_NV21:
|
||||
frag_prog = g_strdup_printf (frag_NV12_NV21_prog, 'a', 'r');
|
||||
free_frag_prog = TRUE;
|
||||
ctx->n_textures = 2;
|
||||
texnames[0] = "Ytex";
|
||||
texnames[1] = "UVtex";
|
||||
break;
|
||||
case GST_VIDEO_FORMAT_BGR:
|
||||
case GST_VIDEO_FORMAT_BGRx:
|
||||
case GST_VIDEO_FORMAT_BGRA:
|
||||
frag_prog = g_strdup_printf (frag_REORDER_prog, 'b', 'g', 'r');
|
||||
free_frag_prog = TRUE;
|
||||
ctx->n_textures = 1;
|
||||
texnames[0] = "tex";
|
||||
break;
|
||||
case GST_VIDEO_FORMAT_xRGB:
|
||||
case GST_VIDEO_FORMAT_ARGB:
|
||||
frag_prog = g_strdup_printf (frag_REORDER_prog, 'g', 'b', 'a');
|
||||
free_frag_prog = TRUE;
|
||||
ctx->n_textures = 1;
|
||||
texnames[0] = "tex";
|
||||
break;
|
||||
case GST_VIDEO_FORMAT_xBGR:
|
||||
case GST_VIDEO_FORMAT_ABGR:
|
||||
frag_prog = g_strdup_printf (frag_REORDER_prog, 'a', 'b', 'g');
|
||||
free_frag_prog = TRUE;
|
||||
ctx->n_textures = 1;
|
||||
texnames[0] = "tex";
|
||||
break;
|
||||
case GST_VIDEO_FORMAT_RGB:
|
||||
case GST_VIDEO_FORMAT_RGBx:
|
||||
case GST_VIDEO_FORMAT_RGBA:
|
||||
case GST_VIDEO_FORMAT_RGB16:
|
||||
frag_prog = (gchar *) frag_COPY_prog;
|
||||
free_frag_prog = FALSE;
|
||||
ctx->n_textures = 1;
|
||||
texnames[0] = "tex";
|
||||
break;
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
break;
|
||||
}
|
||||
|
||||
if (!create_shader_program (ctx,
|
||||
&ctx->glslprogram[0],
|
||||
&ctx->vertshader[0],
|
||||
&ctx->fragshader[0], vert_COPY_prog, frag_prog)) {
|
||||
if (free_frag_prog)
|
||||
g_free (frag_prog);
|
||||
frag_prog = NULL;
|
||||
goto HANDLE_ERROR;
|
||||
}
|
||||
if (free_frag_prog)
|
||||
g_free (frag_prog);
|
||||
frag_prog = NULL;
|
||||
|
||||
ctx->position_loc[0] = glGetAttribLocation (ctx->glslprogram[0], "position");
|
||||
ctx->texpos_loc[0] = glGetAttribLocation (ctx->glslprogram[0], "texpos");
|
||||
ctx->tex_scale_loc[0][0] =
|
||||
glGetUniformLocation (ctx->glslprogram[0], "tex_scale0");
|
||||
ctx->tex_scale_loc[0][1] =
|
||||
glGetUniformLocation (ctx->glslprogram[0], "tex_scale1");
|
||||
ctx->tex_scale_loc[0][2] =
|
||||
glGetUniformLocation (ctx->glslprogram[0], "tex_scale2");
|
||||
|
||||
for (i = 0; i < ctx->n_textures; i++) {
|
||||
ctx->tex_loc[0][i] =
|
||||
glGetUniformLocation (ctx->glslprogram[0], texnames[i]);
|
||||
}
|
||||
|
||||
if (!ctx->buffer_preserved) {
|
||||
/* Build shader program for black borders */
|
||||
if (!create_shader_program (ctx,
|
||||
&ctx->glslprogram[1],
|
||||
&ctx->vertshader[1],
|
||||
&ctx->fragshader[1], vert_COPY_prog_no_tex, frag_BLACK_prog))
|
||||
goto HANDLE_ERROR;
|
||||
|
||||
ctx->position_loc[1] =
|
||||
glGetAttribLocation (ctx->glslprogram[1], "position");
|
||||
}
|
||||
|
||||
/* Generate textures */
|
||||
if (!ctx->have_texture) {
|
||||
GST_INFO_OBJECT (ctx->element, "Performing initial texture setup");
|
||||
|
||||
glGenTextures (ctx->n_textures, ctx->texture);
|
||||
if (got_gl_error ("glGenTextures"))
|
||||
goto HANDLE_ERROR_LOCKED;
|
||||
|
||||
for (i = 0; i < ctx->n_textures; i++) {
|
||||
glBindTexture (GL_TEXTURE_2D, ctx->texture[i]);
|
||||
if (got_gl_error ("glBindTexture"))
|
||||
goto HANDLE_ERROR;
|
||||
|
||||
/* Set 2D resizing params */
|
||||
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
/* If these are not set the texture image unit will return
|
||||
* (R, G, B, A) = black on glTexImage2D for non-POT width/height
|
||||
* frames. For a deeper explanation take a look at the OpenGL ES
|
||||
* documentation for glTexParameter */
|
||||
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
if (got_gl_error ("glTexParameteri"))
|
||||
goto HANDLE_ERROR_LOCKED;
|
||||
}
|
||||
|
||||
ctx->have_texture = TRUE;
|
||||
}
|
||||
|
||||
glUseProgram (0);
|
||||
|
||||
return TRUE;
|
||||
|
||||
/* Errors */
|
||||
HANDLE_ERROR_LOCKED:
|
||||
HANDLE_ERROR:
|
||||
GST_ERROR_OBJECT (ctx->element, "Couldn't setup EGL surface");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gst_egl_adaptation_choose_config (GstEglAdaptationContext * ctx)
|
||||
{
|
||||
gint egl_configs;
|
||||
|
||||
if (!_gst_egl_choose_config (ctx, FALSE, &egl_configs)) {
|
||||
GST_ERROR_OBJECT (ctx->element, "eglChooseConfig failed");
|
||||
goto HANDLE_ERROR;
|
||||
}
|
||||
|
||||
if (egl_configs < 1) {
|
||||
GST_ERROR_OBJECT (ctx->element,
|
||||
"Could not find matching framebuffer config");
|
||||
goto HANDLE_ERROR;
|
||||
}
|
||||
|
||||
if (!gst_egl_adaptation_create_egl_context (ctx)) {
|
||||
GST_ERROR_OBJECT (ctx->element, "Error getting context, eglCreateContext");
|
||||
goto HANDLE_ERROR;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
|
||||
/* Errors */
|
||||
HANDLE_ERROR:
|
||||
GST_ERROR_OBJECT (ctx->element, "Couldn't choose an usable config");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
GstEglAdaptationContext *
|
||||
gst_egl_adaptation_context_new (GstElement * element)
|
||||
{
|
||||
GstEglAdaptationContext *ctx = g_new0 (GstEglAdaptationContext, 1);
|
||||
|
||||
ctx->element = gst_object_ref (element);
|
||||
|
||||
gst_egl_adaptation_init (ctx);
|
||||
return ctx;
|
||||
}
|
||||
|
||||
void
|
||||
gst_egl_adaptation_context_free (GstEglAdaptationContext * ctx)
|
||||
{
|
||||
gst_egl_adaptation_deinit (ctx);
|
||||
if (GST_OBJECT_REFCOUNT(ctx->element))
|
||||
gst_object_unref (ctx->element);
|
||||
g_free (ctx);
|
||||
}
|
||||
|
||||
gboolean
|
||||
gst_egl_adaptation_reset_window (GstEglAdaptationContext * ctx,
|
||||
GstVideoFormat format)
|
||||
{
|
||||
if (!gst_egl_adaptation_context_make_current (ctx, FALSE))
|
||||
return FALSE;
|
||||
|
||||
gst_egl_adaptation_destroy_surface (ctx);
|
||||
|
||||
ctx->used_window = ctx->window;
|
||||
|
||||
if (!gst_egl_adaptation_init_surface (ctx, format))
|
||||
return FALSE;
|
||||
|
||||
if (!gst_egl_adaptation_context_make_current (ctx, TRUE))
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
202
gstegl_src/gst-egl/ext/eglgles/gstegladaptation.h
Normal file
202
gstegl_src/gst-egl/ext/eglgles/gstegladaptation.h
Normal file
@@ -0,0 +1,202 @@
|
||||
/*
|
||||
* GStreamer EGL/GLES Sink Adaptation
|
||||
* Copyright (C) 2012-2013 Collabora Ltd.
|
||||
* @author: Reynaldo H. Verdejo Pinochet <reynaldo@collabora.com>
|
||||
* @author: Sebastian Dröge <sebastian.droege@collabora.co.uk>
|
||||
* @author: Thiago Santos <thiago.sousa.santos@collabora.com>
|
||||
* Copyright (c) 2015, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef __GST_EGL_ADAPTATION_H__
|
||||
#define __GST_EGL_ADAPTATION_H__
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <gst/gst.h>
|
||||
#include <gst/video/gstvideopool.h>
|
||||
|
||||
#if defined (USE_EGL_RPI) && defined(__GNUC__)
|
||||
#ifndef __VCCOREVER__
|
||||
#define __VCCOREVER__ 0x04000000
|
||||
#endif
|
||||
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wredundant-decls"
|
||||
#pragma GCC optimize ("gnu89-inline")
|
||||
#endif
|
||||
|
||||
#define EGL_EGLEXT_PROTOTYPES
|
||||
#define GL_GLEXT_PROTOTYPES
|
||||
|
||||
#ifdef HAVE_IOS
|
||||
#include <OpenGLES/ES2/gl.h>
|
||||
#else
|
||||
#include <gst/egl/egl.h>
|
||||
#include <EGL/egl.h>
|
||||
#include <EGL/eglext.h>
|
||||
#include <GLES2/gl2.h>
|
||||
#include <GLES2/gl2ext.h>
|
||||
#endif
|
||||
|
||||
#if defined (USE_EGL_RPI) && defined(__GNUC__)
|
||||
#pragma GCC reset_options
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
typedef struct _GstEglAdaptationContext GstEglAdaptationContext;
|
||||
typedef struct _GstEglGlesImageFmt GstEglGlesImageFmt;
|
||||
|
||||
#ifdef HAVE_IOS
|
||||
typedef struct _GstEaglContext GstEaglContext;
|
||||
#else
|
||||
typedef struct _GstEglGlesRenderContext GstEglGlesRenderContext;
|
||||
#endif
|
||||
|
||||
typedef struct _coord5
|
||||
{
|
||||
float x;
|
||||
float y;
|
||||
float z;
|
||||
float a; /* texpos x */
|
||||
float b; /* texpos y */
|
||||
} coord5;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
GLuint texture;
|
||||
EGLDisplay display;
|
||||
EGLContext eglcontext;
|
||||
} GstEGLGLESImageData;
|
||||
|
||||
/*
|
||||
* GstEglAdaptationContext:
|
||||
* @have_vbo: Set if the GLES VBO setup has been performed
|
||||
* @have_texture: Set if the GLES texture setup has been performed
|
||||
* @have_surface: Set if the EGL surface setup has been performed
|
||||
*
|
||||
* The #GstEglAdaptationContext data structure.
|
||||
*/
|
||||
struct _GstEglAdaptationContext
|
||||
{
|
||||
GstElement *element;
|
||||
|
||||
#ifdef HAVE_IOS
|
||||
GstEaglContext *eaglctx;
|
||||
void * window, *used_window;
|
||||
#else
|
||||
GstEglGlesRenderContext *eglglesctx;
|
||||
GstEGLDisplay *display, *set_display;
|
||||
EGLNativeWindowType window, used_window;
|
||||
#endif
|
||||
|
||||
GLuint fragshader[2]; /* frame, border */
|
||||
GLuint vertshader[2]; /* frame, border */
|
||||
GLuint glslprogram[2]; /* frame, border */
|
||||
GLuint texture[3]; /* RGB/Y, U/UV, V */
|
||||
/* shader vars */
|
||||
GLuint position_loc[2]; /* frame, border */
|
||||
GLuint texpos_loc[1]; /* frame */
|
||||
GLuint tex_scale_loc[1][3]; /* [frame] RGB/Y, U/UV, V */
|
||||
GLuint tex_loc[1][3]; /* [frame] RGB/Y, U/UV, V */
|
||||
coord5 position_array[16]; /* 4 x Frame x-normal,y-normal, 4x Frame x-normal,y-flip, 4 x Border1, 4 x Border2 */
|
||||
unsigned short index_array[4];
|
||||
unsigned int position_buffer, index_buffer;
|
||||
gint n_textures;
|
||||
|
||||
gint surface_width;
|
||||
gint surface_height;
|
||||
gint pixel_aspect_ratio_n;
|
||||
gint pixel_aspect_ratio_d;
|
||||
|
||||
gboolean have_vbo;
|
||||
gboolean have_texture;
|
||||
gboolean have_surface;
|
||||
gboolean buffer_preserved;
|
||||
};
|
||||
|
||||
GST_DEBUG_CATEGORY_EXTERN (egladaption_debug);
|
||||
|
||||
void gst_egl_adaption_init (void);
|
||||
|
||||
GstEglAdaptationContext * gst_egl_adaptation_context_new (GstElement * element);
|
||||
void gst_egl_adaptation_context_free (GstEglAdaptationContext * ctx);
|
||||
void gst_egl_adaptation_init (GstEglAdaptationContext * ctx);
|
||||
void gst_egl_adaptation_deinit (GstEglAdaptationContext * ctx);
|
||||
|
||||
gboolean gst_egl_adaptation_create_surface (GstEglAdaptationContext * ctx);
|
||||
void gst_egl_adaptation_query_buffer_preserved (GstEglAdaptationContext * ctx);
|
||||
void gst_egl_adaptation_query_par (GstEglAdaptationContext * ctx);
|
||||
void gst_egl_adaptation_destroy_surface (GstEglAdaptationContext * ctx);
|
||||
void gst_egl_adaptation_destroy_context (GstEglAdaptationContext * ctx);
|
||||
void gst_egl_adaptation_release_thread (void);
|
||||
|
||||
gboolean
|
||||
gst_egl_adaptation_create_egl_context (GstEglAdaptationContext * ctx);
|
||||
|
||||
#ifndef HAVE_IOS
|
||||
EGLContext gst_egl_adaptation_context_get_egl_context (GstEglAdaptationContext * ctx);
|
||||
#endif
|
||||
|
||||
/* platform window */
|
||||
gboolean gst_egl_adaptation_create_native_window (GstEglAdaptationContext
|
||||
* ctx, gint width, gint height, gpointer * own_window_data, gchar* winsys);
|
||||
void gst_egl_adaptation_destroy_native_window (GstEglAdaptationContext * ctx, gpointer * own_window_data, gchar* winsys);
|
||||
|
||||
GstCaps *gst_egl_adaptation_fill_supported_fbuffer_configs (GstEglAdaptationContext * ctx);
|
||||
gboolean gst_egl_adaptation_init_display (GstEglAdaptationContext * ctx, gchar* winsys);
|
||||
gboolean gst_egl_adaptation_choose_config (GstEglAdaptationContext * ctx);
|
||||
gboolean gst_egl_adaptation_init_surface (GstEglAdaptationContext * ctx, GstVideoFormat format);
|
||||
void gst_egl_adaptation_init_exts (GstEglAdaptationContext * ctx);
|
||||
gboolean gst_egl_adaptation_update_surface_dimensions (GstEglAdaptationContext * ctx);
|
||||
gboolean _gst_egl_choose_config (GstEglAdaptationContext * ctx, gboolean try_only, gint * num_configs);
|
||||
|
||||
gboolean got_gl_error (const char *wtf);
|
||||
gboolean got_egl_error (const char *wtf);
|
||||
|
||||
void gst_egl_adaptation_set_window (GstEglAdaptationContext * ctx, guintptr window);
|
||||
|
||||
gboolean gst_egl_adaptation_context_make_current (GstEglAdaptationContext * ctx, gboolean bind);
|
||||
void gst_egl_adaptation_cleanup (GstEglAdaptationContext * ctx);
|
||||
|
||||
void gst_egl_adaptation_bind_API (GstEglAdaptationContext * ctx);
|
||||
|
||||
gboolean gst_egl_adaptation_context_swap_buffers (GstEglAdaptationContext * ctx);
|
||||
|
||||
gboolean gst_egl_adaptation_reset_window (GstEglAdaptationContext * ctx, GstVideoFormat format);
|
||||
|
||||
#ifndef HAVE_IOS
|
||||
/* TODO: The goal is to move this function to gstegl lib (or
|
||||
* splitted between gstegl lib and gstgl lib) in order to be used in
|
||||
* webkitVideoSink
|
||||
* So it has to be independent of GstEglAdaptationContext */
|
||||
GstBuffer *
|
||||
gst_egl_image_allocator_alloc_eglimage (GstAllocator * allocator,
|
||||
GstEGLDisplay * display, EGLContext eglcontext, GstVideoFormat format,
|
||||
gint width, gint height);
|
||||
#endif
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GST_EGL_ADAPTATION_H__ */
|
||||
964
gstegl_src/gst-egl/ext/eglgles/gstegladaptation_egl.c
Normal file
964
gstegl_src/gst-egl/ext/eglgles/gstegladaptation_egl.c
Normal file
@@ -0,0 +1,964 @@
|
||||
/*
|
||||
* Copyright (C) 2012-2013 Collabora Ltd.
|
||||
* @author: Reynaldo H. Verdejo Pinochet <reynaldo@collabora.com>
|
||||
* @author: Sebastian Dröge <sebastian.droege@collabora.co.uk>
|
||||
* @author: Thiago Santos <thiago.sousa.santos@collabora.com>
|
||||
* Copyright (c) 2015-2016, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "gstegladaptation.h"
|
||||
#include "gsteglglessink.h"
|
||||
#include "video_platform_wrapper.h"
|
||||
#include <string.h>
|
||||
|
||||
#include <EGL/egl.h>
|
||||
#include <EGL/eglext.h>
|
||||
#include <GLES2/gl2.h>
|
||||
#include <GLES2/gl2ext.h>
|
||||
#include <gst/egl/egl.h>
|
||||
|
||||
#define GST_CAT_DEFAULT egladaption_debug
|
||||
|
||||
/* Some EGL implementations are reporting wrong
|
||||
* values for the display's EGL_PIXEL_ASPECT_RATIO.
|
||||
* They are required by the khronos specs to report
|
||||
* this value as w/h * EGL_DISPLAY_SCALING (Which is
|
||||
* a constant with value 10000) but at least the
|
||||
* Galaxy SIII (Android) is reporting just 1 when
|
||||
* w = h. We use these two to bound returned values to
|
||||
* sanity.
|
||||
*/
|
||||
#define EGL_SANE_DAR_MIN ((EGL_DISPLAY_SCALING)/10)
|
||||
#define EGL_SANE_DAR_MAX ((EGL_DISPLAY_SCALING)*10)
|
||||
|
||||
#define GST_EGLGLESSINK_EGL_MIN_VERSION 1
|
||||
|
||||
static const EGLint eglglessink_RGBA8888_attribs[] = {
|
||||
EGL_RED_SIZE, 8,
|
||||
EGL_GREEN_SIZE, 8,
|
||||
EGL_BLUE_SIZE, 8,
|
||||
EGL_ALPHA_SIZE, 8,
|
||||
EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
|
||||
EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
|
||||
EGL_NONE
|
||||
};
|
||||
|
||||
/*
|
||||
* GstEglGlesRenderContext:
|
||||
* @config: Current EGL config
|
||||
* @eglcontext: Current EGL context
|
||||
* @egl_minor: EGL version (minor)
|
||||
* @egl_major: EGL version (major)
|
||||
*
|
||||
* This struct holds the sink's EGL/GLES rendering context.
|
||||
*/
|
||||
struct _GstEglGlesRenderContext
|
||||
{
|
||||
EGLConfig config;
|
||||
EGLContext eglcontext;
|
||||
EGLSurface surface;
|
||||
EGLint egl_minor, egl_major;
|
||||
};
|
||||
|
||||
gboolean
|
||||
got_egl_error (const char *wtf)
|
||||
{
|
||||
EGLint error;
|
||||
|
||||
if ((error = eglGetError ()) != EGL_SUCCESS) {
|
||||
GST_CAT_DEBUG (GST_CAT_DEFAULT, "EGL ERROR: %s returned 0x%04x", wtf,
|
||||
error);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Prints available EGL/GLES extensions
|
||||
* If another rendering path is implemented this is the place
|
||||
* where you want to check for the availability of its supporting
|
||||
* EGL/GLES extensions.
|
||||
*/
|
||||
void
|
||||
gst_egl_adaptation_init_exts (GstEglAdaptationContext * ctx)
|
||||
{
|
||||
#ifndef GST_DISABLE_GST_DEBUG
|
||||
const char *eglexts;
|
||||
unsigned const char *glexts;
|
||||
|
||||
eglexts = eglQueryString (gst_egl_display_get (ctx->display), EGL_EXTENSIONS);
|
||||
glexts = glGetString (GL_EXTENSIONS);
|
||||
|
||||
GST_DEBUG_OBJECT (ctx->element, "Available EGL extensions: %s\n",
|
||||
GST_STR_NULL (eglexts));
|
||||
GST_DEBUG_OBJECT (ctx->element, "Available GLES extensions: %s\n",
|
||||
GST_STR_NULL ((const char *) glexts));
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gst_egl_adaptation_init_display (GstEglAdaptationContext * ctx, gchar* winsys)
|
||||
{
|
||||
GstMessage *msg;
|
||||
GstEglGlesSink *sink = (GstEglGlesSink *) ctx->element;
|
||||
EGLDisplay display = EGL_NO_DISPLAY;
|
||||
GST_DEBUG_OBJECT (ctx->element, "Enter EGL initial configuration");
|
||||
|
||||
if (!platform_wrapper_init ()) {
|
||||
GST_ERROR_OBJECT (ctx->element, "Couldn't init EGL platform wrapper");
|
||||
goto HANDLE_ERROR;
|
||||
}
|
||||
|
||||
msg =
|
||||
gst_message_new_need_context (GST_OBJECT_CAST (ctx->element),
|
||||
GST_EGL_DISPLAY_CONTEXT_TYPE);
|
||||
gst_element_post_message (GST_ELEMENT_CAST (ctx->element), msg);
|
||||
|
||||
GST_OBJECT_LOCK (ctx->element);
|
||||
if (!ctx->set_display) {
|
||||
GstContext *context;
|
||||
|
||||
GST_OBJECT_UNLOCK (ctx->element);
|
||||
|
||||
#ifdef USE_EGL_WAYLAND
|
||||
if (g_strcmp0(winsys, "wayland") == 0) {
|
||||
display = eglGetDisplay (platform_initialize_display_wayland());
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef USE_EGL_X11
|
||||
if (g_strcmp0(winsys, "x11") == 0) {
|
||||
display = eglGetDisplay (sink->display);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (display == EGL_NO_DISPLAY) {
|
||||
GST_ERROR_OBJECT (ctx->element, "Could not get EGL display connection");
|
||||
goto HANDLE_ERROR; /* No EGL error is set by eglGetDisplay() */
|
||||
}
|
||||
ctx->display = gst_egl_display_new (display, NULL);
|
||||
|
||||
context = gst_context_new_egl_display (ctx->display, FALSE);
|
||||
msg = gst_message_new_have_context (GST_OBJECT (ctx->element), context);
|
||||
gst_element_post_message (GST_ELEMENT_CAST (ctx->element), msg);
|
||||
} else {
|
||||
ctx->display = ctx->set_display;
|
||||
GST_OBJECT_UNLOCK (ctx->element);
|
||||
}
|
||||
|
||||
if (!eglInitialize (gst_egl_display_get (ctx->display),
|
||||
&ctx->eglglesctx->egl_major, &ctx->eglglesctx->egl_minor)) {
|
||||
got_egl_error ("eglInitialize");
|
||||
GST_ERROR_OBJECT (ctx->element, "Could not init EGL display connection");
|
||||
goto HANDLE_EGL_ERROR;
|
||||
}
|
||||
|
||||
/* Check against required EGL version
|
||||
* XXX: Need to review the version requirement in terms of the needed API
|
||||
*/
|
||||
if (ctx->eglglesctx->egl_major < GST_EGLGLESSINK_EGL_MIN_VERSION) {
|
||||
GST_ERROR_OBJECT (ctx->element, "EGL v%d needed, but you only have v%d.%d",
|
||||
GST_EGLGLESSINK_EGL_MIN_VERSION, ctx->eglglesctx->egl_major,
|
||||
ctx->eglglesctx->egl_minor);
|
||||
goto HANDLE_ERROR;
|
||||
}
|
||||
|
||||
GST_INFO_OBJECT (ctx->element, "System reports supported EGL version v%d.%d",
|
||||
ctx->eglglesctx->egl_major, ctx->eglglesctx->egl_minor);
|
||||
|
||||
eglBindAPI (EGL_OPENGL_ES_API);
|
||||
|
||||
return TRUE;
|
||||
|
||||
/* Errors */
|
||||
HANDLE_EGL_ERROR:
|
||||
GST_ERROR_OBJECT (ctx->element, "EGL call returned error %x", eglGetError ());
|
||||
HANDLE_ERROR:
|
||||
GST_ERROR_OBJECT (ctx->element, "Couldn't setup window/surface from handle");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gst_egl_adaptation_context_make_current (GstEglAdaptationContext * ctx,
|
||||
gboolean bind)
|
||||
{
|
||||
g_assert (ctx->display != NULL);
|
||||
|
||||
if (bind && ctx->eglglesctx->surface && ctx->eglglesctx->eglcontext) {
|
||||
EGLContext *cur_ctx = eglGetCurrentContext ();
|
||||
|
||||
if (cur_ctx == ctx->eglglesctx->eglcontext) {
|
||||
GST_DEBUG_OBJECT (ctx->element,
|
||||
"Already attached the context to thread %p", g_thread_self ());
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
GST_DEBUG_OBJECT (ctx->element, "Attaching context to thread %p",
|
||||
g_thread_self ());
|
||||
if (!eglMakeCurrent (gst_egl_display_get (ctx->display),
|
||||
ctx->eglglesctx->surface, ctx->eglglesctx->surface,
|
||||
ctx->eglglesctx->eglcontext)) {
|
||||
got_egl_error ("eglMakeCurrent");
|
||||
GST_ERROR_OBJECT (ctx->element, "Couldn't bind context");
|
||||
return FALSE;
|
||||
}
|
||||
} else {
|
||||
GST_DEBUG_OBJECT (ctx->element, "Detaching context from thread %p",
|
||||
g_thread_self ());
|
||||
if (!eglMakeCurrent (gst_egl_display_get (ctx->display),
|
||||
EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT)) {
|
||||
got_egl_error ("eglMakeCurrent");
|
||||
GST_ERROR_OBJECT (ctx->element, "Couldn't unbind context");
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* XXX: Lock eglgles context? */
|
||||
gboolean
|
||||
gst_egl_adaptation_update_surface_dimensions (GstEglAdaptationContext * ctx)
|
||||
{
|
||||
gint width, height;
|
||||
|
||||
/* Save surface dims */
|
||||
eglQuerySurface (gst_egl_display_get (ctx->display),
|
||||
ctx->eglglesctx->surface, EGL_WIDTH, &width);
|
||||
eglQuerySurface (gst_egl_display_get (ctx->display),
|
||||
ctx->eglglesctx->surface, EGL_HEIGHT, &height);
|
||||
|
||||
if (width != ctx->surface_width || height != ctx->surface_height) {
|
||||
ctx->surface_width = width;
|
||||
ctx->surface_height = height;
|
||||
GST_INFO_OBJECT (ctx->element, "Got surface of %dx%d pixels", width,
|
||||
height);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void
|
||||
gst_egl_adaptation_bind_API (GstEglAdaptationContext * ctx)
|
||||
{
|
||||
eglBindAPI (EGL_OPENGL_ES_API);
|
||||
}
|
||||
|
||||
gboolean
|
||||
gst_egl_adaptation_context_swap_buffers (GstEglAdaptationContext * ctx)
|
||||
{
|
||||
gboolean ret = eglSwapBuffers (gst_egl_display_get (ctx->display),
|
||||
ctx->eglglesctx->surface);
|
||||
if (ret == EGL_FALSE) {
|
||||
got_egl_error ("eglSwapBuffers");
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
gboolean
|
||||
_gst_egl_choose_config (GstEglAdaptationContext * ctx, gboolean try_only,
|
||||
gint * num_configs)
|
||||
{
|
||||
EGLint cfg_number;
|
||||
gboolean ret;
|
||||
EGLConfig *config = NULL;
|
||||
|
||||
if (!try_only)
|
||||
config = &ctx->eglglesctx->config;
|
||||
|
||||
ret = eglChooseConfig (gst_egl_display_get (ctx->display),
|
||||
eglglessink_RGBA8888_attribs, config, 1, &cfg_number) != EGL_FALSE;
|
||||
|
||||
if (!ret)
|
||||
got_egl_error ("eglChooseConfig");
|
||||
else if (num_configs)
|
||||
*num_configs = cfg_number;
|
||||
return ret;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gst_egl_adaptation_create_surface (GstEglAdaptationContext * ctx)
|
||||
{
|
||||
ctx->eglglesctx->surface =
|
||||
eglCreateWindowSurface (gst_egl_display_get (ctx->display),
|
||||
ctx->eglglesctx->config, ctx->used_window, NULL);
|
||||
|
||||
if (ctx->eglglesctx->surface == EGL_NO_SURFACE) {
|
||||
got_egl_error ("eglCreateWindowSurface");
|
||||
GST_ERROR_OBJECT (ctx->element, "Can't create surface");
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
gst_egl_adaptation_query_buffer_preserved (GstEglAdaptationContext * ctx)
|
||||
{
|
||||
EGLint swap_behavior;
|
||||
|
||||
ctx->buffer_preserved = FALSE;
|
||||
if (eglQuerySurface (gst_egl_display_get (ctx->display),
|
||||
ctx->eglglesctx->surface, EGL_SWAP_BEHAVIOR, &swap_behavior)) {
|
||||
GST_DEBUG_OBJECT (ctx->element, "Buffer swap behavior %x", swap_behavior);
|
||||
ctx->buffer_preserved = swap_behavior == EGL_BUFFER_PRESERVED;
|
||||
} else {
|
||||
GST_DEBUG_OBJECT (ctx->element, "Can't query buffer swap behavior");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
gst_egl_adaptation_query_par (GstEglAdaptationContext * ctx)
|
||||
{
|
||||
EGLint display_par;
|
||||
|
||||
/* fixed value */
|
||||
ctx->pixel_aspect_ratio_d = EGL_DISPLAY_SCALING;
|
||||
|
||||
/* Save display's pixel aspect ratio
|
||||
*
|
||||
* DAR is reported as w/h * EGL_DISPLAY_SCALING wich is
|
||||
* a constant with value 10000. This attribute is only
|
||||
* supported if the EGL version is >= 1.2
|
||||
* XXX: Setup this as a property.
|
||||
* or some other one time check. Right now it's being called once
|
||||
* per frame.
|
||||
*/
|
||||
if (ctx->eglglesctx->egl_major == 1 && ctx->eglglesctx->egl_minor < 2) {
|
||||
GST_DEBUG_OBJECT (ctx->element, "Can't query PAR. Using default: %dx%d",
|
||||
EGL_DISPLAY_SCALING, EGL_DISPLAY_SCALING);
|
||||
ctx->pixel_aspect_ratio_n = EGL_DISPLAY_SCALING;
|
||||
} else {
|
||||
eglQuerySurface (gst_egl_display_get (ctx->display),
|
||||
ctx->eglglesctx->surface, EGL_PIXEL_ASPECT_RATIO, &display_par);
|
||||
/* Fix for outbound DAR reporting on some implementations not
|
||||
* honoring the 'should return w/h * EGL_DISPLAY_SCALING' spec
|
||||
* requirement
|
||||
*/
|
||||
if (display_par == EGL_UNKNOWN || display_par < EGL_SANE_DAR_MIN ||
|
||||
display_par > EGL_SANE_DAR_MAX) {
|
||||
GST_DEBUG_OBJECT (ctx->element, "Nonsensical PAR value returned: %d. "
|
||||
"Bad EGL implementation? "
|
||||
"Will use default: %d/%d", ctx->pixel_aspect_ratio_n,
|
||||
EGL_DISPLAY_SCALING, EGL_DISPLAY_SCALING);
|
||||
ctx->pixel_aspect_ratio_n = EGL_DISPLAY_SCALING;
|
||||
} else {
|
||||
ctx->pixel_aspect_ratio_n = display_par;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
gboolean
|
||||
gst_egl_adaptation_create_egl_context (GstEglAdaptationContext * ctx)
|
||||
{
|
||||
EGLint con_attribs[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE };
|
||||
|
||||
ctx->eglglesctx->eglcontext =
|
||||
eglCreateContext (gst_egl_display_get (ctx->display),
|
||||
ctx->eglglesctx->config, EGL_NO_CONTEXT, con_attribs);
|
||||
|
||||
if (ctx->eglglesctx->eglcontext == EGL_NO_CONTEXT) {
|
||||
GST_ERROR_OBJECT (ctx->element, "EGL call returned error %x",
|
||||
eglGetError ());
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
GST_DEBUG_OBJECT (ctx->element, "EGL Context: %p",
|
||||
ctx->eglglesctx->eglcontext);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
EGLContext
|
||||
gst_egl_adaptation_context_get_egl_context (GstEglAdaptationContext * ctx)
|
||||
{
|
||||
g_return_val_if_fail (ctx != NULL, EGL_NO_CONTEXT);
|
||||
|
||||
return ctx->eglglesctx->eglcontext;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_egl_gles_image_data_free (GstEGLGLESImageData * data)
|
||||
{
|
||||
if (!eglMakeCurrent (data->display,
|
||||
EGL_NO_SURFACE, EGL_NO_SURFACE, data->eglcontext)) {
|
||||
got_egl_error ("eglMakeCurrent");
|
||||
g_slice_free (GstEGLGLESImageData, data);
|
||||
return;
|
||||
}
|
||||
glDeleteTextures (1, &data->texture);
|
||||
g_slice_free (GstEGLGLESImageData, data);
|
||||
}
|
||||
|
||||
|
||||
GstBuffer *
|
||||
gst_egl_image_allocator_alloc_eglimage (GstAllocator * allocator,
|
||||
GstEGLDisplay * display, EGLContext eglcontext, GstVideoFormat format,
|
||||
gint width, gint height)
|
||||
{
|
||||
GstEGLGLESImageData *data = NULL;
|
||||
GstBuffer *buffer;
|
||||
GstVideoInfo info;
|
||||
guint i;
|
||||
gint stride[3];
|
||||
gsize offset[3];
|
||||
GstMemory *mem[3] = { NULL, NULL, NULL };
|
||||
guint n_mem;
|
||||
GstMemoryFlags flags = 0;
|
||||
|
||||
memset (stride, 0, sizeof (stride));
|
||||
memset (offset, 0, sizeof (offset));
|
||||
|
||||
if (!gst_egl_image_memory_is_mappable ())
|
||||
flags |= GST_MEMORY_FLAG_NOT_MAPPABLE;
|
||||
/* See https://bugzilla.gnome.org/show_bug.cgi?id=695203 */
|
||||
flags |= GST_MEMORY_FLAG_NO_SHARE;
|
||||
|
||||
gst_video_info_set_format (&info, format, width, height);
|
||||
|
||||
switch (format) {
|
||||
case GST_VIDEO_FORMAT_RGB:
|
||||
case GST_VIDEO_FORMAT_BGR:{
|
||||
gsize size;
|
||||
EGLImageKHR image;
|
||||
|
||||
mem[0] =
|
||||
gst_egl_image_allocator_alloc (allocator, display,
|
||||
GST_VIDEO_GL_TEXTURE_TYPE_RGB, GST_VIDEO_INFO_WIDTH (&info),
|
||||
GST_VIDEO_INFO_HEIGHT (&info), &size);
|
||||
if (mem[0]) {
|
||||
stride[0] = size / GST_VIDEO_INFO_HEIGHT (&info);
|
||||
n_mem = 1;
|
||||
GST_MINI_OBJECT_FLAG_SET (mem[0], GST_MEMORY_FLAG_NO_SHARE);
|
||||
} else {
|
||||
data = g_slice_new0 (GstEGLGLESImageData);
|
||||
data->display = gst_egl_display_get (display);
|
||||
data->eglcontext = eglcontext;
|
||||
|
||||
stride[0] = GST_ROUND_UP_4 (GST_VIDEO_INFO_WIDTH (&info) * 3);
|
||||
size = stride[0] * GST_VIDEO_INFO_HEIGHT (&info);
|
||||
|
||||
glGenTextures (1, &data->texture);
|
||||
if (got_gl_error ("glGenTextures"))
|
||||
goto mem_error;
|
||||
|
||||
glBindTexture (GL_TEXTURE_2D, data->texture);
|
||||
if (got_gl_error ("glBindTexture"))
|
||||
goto mem_error;
|
||||
|
||||
/* Set 2D resizing params */
|
||||
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
|
||||
/* If these are not set the texture image unit will return
|
||||
* * (R, G, B, A) = black on glTexImage2D for non-POT width/height
|
||||
* * frames. For a deeper explanation take a look at the OpenGL ES
|
||||
* * documentation for glTexParameter */
|
||||
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
if (got_gl_error ("glTexParameteri"))
|
||||
goto mem_error;
|
||||
|
||||
glTexImage2D (GL_TEXTURE_2D, 0, GL_RGB,
|
||||
GST_VIDEO_INFO_WIDTH (&info),
|
||||
GST_VIDEO_INFO_HEIGHT (&info), 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
|
||||
if (got_gl_error ("glTexImage2D"))
|
||||
goto mem_error;
|
||||
|
||||
image =
|
||||
gst_egl_display_image_create (display,
|
||||
eglcontext, EGL_GL_TEXTURE_2D_KHR,
|
||||
(EGLClientBuffer) (uintptr_t) data->texture, NULL);
|
||||
if (got_egl_error ("eglCreateImageKHR"))
|
||||
goto mem_error;
|
||||
|
||||
mem[0] =
|
||||
gst_egl_image_allocator_wrap (allocator, display,
|
||||
image, GST_VIDEO_GL_TEXTURE_TYPE_RGB,
|
||||
flags, size, data, (GDestroyNotify) gst_egl_gles_image_data_free);
|
||||
n_mem = 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case GST_VIDEO_FORMAT_RGB16:{
|
||||
EGLImageKHR image;
|
||||
gsize size;
|
||||
|
||||
mem[0] =
|
||||
gst_egl_image_allocator_alloc (allocator, display,
|
||||
GST_VIDEO_GL_TEXTURE_TYPE_RGB, GST_VIDEO_INFO_WIDTH (&info),
|
||||
GST_VIDEO_INFO_HEIGHT (&info), &size);
|
||||
if (mem[0]) {
|
||||
stride[0] = size / GST_VIDEO_INFO_HEIGHT (&info);
|
||||
n_mem = 1;
|
||||
GST_MINI_OBJECT_FLAG_SET (mem[0], GST_MEMORY_FLAG_NO_SHARE);
|
||||
} else {
|
||||
data = g_slice_new0 (GstEGLGLESImageData);
|
||||
data->display = gst_egl_display_get (display);
|
||||
data->eglcontext = eglcontext;
|
||||
|
||||
stride[0] = GST_ROUND_UP_4 (GST_VIDEO_INFO_WIDTH (&info) * 2);
|
||||
size = stride[0] * GST_VIDEO_INFO_HEIGHT (&info);
|
||||
|
||||
glGenTextures (1, &data->texture);
|
||||
if (got_gl_error ("glGenTextures"))
|
||||
goto mem_error;
|
||||
|
||||
glBindTexture (GL_TEXTURE_2D, data->texture);
|
||||
if (got_gl_error ("glBindTexture"))
|
||||
goto mem_error;
|
||||
|
||||
/* Set 2D resizing params */
|
||||
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
|
||||
/* If these are not set the texture image unit will return
|
||||
* * (R, G, B, A) = black on glTexImage2D for non-POT width/height
|
||||
* * frames. For a deeper explanation take a look at the OpenGL ES
|
||||
* * documentation for glTexParameter */
|
||||
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
if (got_gl_error ("glTexParameteri"))
|
||||
goto mem_error;
|
||||
|
||||
glTexImage2D (GL_TEXTURE_2D, 0, GL_RGB,
|
||||
GST_VIDEO_INFO_WIDTH (&info),
|
||||
GST_VIDEO_INFO_HEIGHT (&info), 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5,
|
||||
NULL);
|
||||
if (got_gl_error ("glTexImage2D"))
|
||||
goto mem_error;
|
||||
|
||||
image =
|
||||
gst_egl_display_image_create (display,
|
||||
eglcontext, EGL_GL_TEXTURE_2D_KHR,
|
||||
(EGLClientBuffer) (uintptr_t) data->texture, NULL);
|
||||
if (got_egl_error ("eglCreateImageKHR"))
|
||||
goto mem_error;
|
||||
|
||||
mem[0] =
|
||||
gst_egl_image_allocator_wrap (allocator, display,
|
||||
image, GST_VIDEO_GL_TEXTURE_TYPE_RGB,
|
||||
flags, size, data, (GDestroyNotify) gst_egl_gles_image_data_free);
|
||||
n_mem = 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case GST_VIDEO_FORMAT_NV12:
|
||||
case GST_VIDEO_FORMAT_NV21:{
|
||||
EGLImageKHR image;
|
||||
gsize size[2];
|
||||
|
||||
mem[0] =
|
||||
gst_egl_image_allocator_alloc (allocator, display,
|
||||
GST_VIDEO_GL_TEXTURE_TYPE_LUMINANCE, GST_VIDEO_INFO_COMP_WIDTH (&info,
|
||||
0), GST_VIDEO_INFO_COMP_HEIGHT (&info, 0), &size[0]);
|
||||
mem[1] =
|
||||
gst_egl_image_allocator_alloc (allocator, display,
|
||||
GST_VIDEO_GL_TEXTURE_TYPE_LUMINANCE_ALPHA,
|
||||
GST_VIDEO_INFO_COMP_WIDTH (&info, 1),
|
||||
GST_VIDEO_INFO_COMP_HEIGHT (&info, 1), &size[1]);
|
||||
|
||||
if (mem[0] && mem[1]) {
|
||||
stride[0] = size[0] / GST_VIDEO_INFO_HEIGHT (&info);
|
||||
offset[1] = size[0];
|
||||
stride[1] = size[1] / GST_VIDEO_INFO_HEIGHT (&info);
|
||||
n_mem = 2;
|
||||
GST_MINI_OBJECT_FLAG_SET (mem[0], GST_MEMORY_FLAG_NO_SHARE);
|
||||
GST_MINI_OBJECT_FLAG_SET (mem[1], GST_MEMORY_FLAG_NO_SHARE);
|
||||
} else {
|
||||
if (mem[0])
|
||||
gst_memory_unref (mem[0]);
|
||||
if (mem[1])
|
||||
gst_memory_unref (mem[1]);
|
||||
mem[0] = mem[1] = NULL;
|
||||
|
||||
stride[0] = GST_ROUND_UP_4 (GST_VIDEO_INFO_COMP_WIDTH (&info, 0));
|
||||
stride[1] = GST_ROUND_UP_4 (GST_VIDEO_INFO_COMP_WIDTH (&info, 1) * 2);
|
||||
offset[1] = stride[0] * GST_VIDEO_INFO_COMP_HEIGHT (&info, 0);
|
||||
size[0] = offset[1];
|
||||
size[1] = stride[1] * GST_VIDEO_INFO_COMP_HEIGHT (&info, 1);
|
||||
|
||||
for (i = 0; i < 2; i++) {
|
||||
data = g_slice_new0 (GstEGLGLESImageData);
|
||||
data->display = gst_egl_display_get (display);
|
||||
data->eglcontext = eglcontext;
|
||||
|
||||
glGenTextures (1, &data->texture);
|
||||
if (got_gl_error ("glGenTextures"))
|
||||
goto mem_error;
|
||||
|
||||
glBindTexture (GL_TEXTURE_2D, data->texture);
|
||||
if (got_gl_error ("glBindTexture"))
|
||||
goto mem_error;
|
||||
|
||||
/* Set 2D resizing params */
|
||||
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
|
||||
/* If these are not set the texture image unit will return
|
||||
* * (R, G, B, A) = black on glTexImage2D for non-POT width/height
|
||||
* * frames. For a deeper explanation take a look at the OpenGL ES
|
||||
* * documentation for glTexParameter */
|
||||
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
if (got_gl_error ("glTexParameteri"))
|
||||
goto mem_error;
|
||||
|
||||
if (i == 0)
|
||||
glTexImage2D (GL_TEXTURE_2D, 0, GL_LUMINANCE,
|
||||
GST_VIDEO_INFO_COMP_WIDTH (&info, i),
|
||||
GST_VIDEO_INFO_COMP_HEIGHT (&info, i), 0, GL_LUMINANCE,
|
||||
GL_UNSIGNED_BYTE, NULL);
|
||||
else
|
||||
glTexImage2D (GL_TEXTURE_2D, 0, GL_LUMINANCE_ALPHA,
|
||||
GST_VIDEO_INFO_COMP_WIDTH (&info, i),
|
||||
GST_VIDEO_INFO_COMP_HEIGHT (&info, i), 0, GL_LUMINANCE_ALPHA,
|
||||
GL_UNSIGNED_BYTE, NULL);
|
||||
|
||||
if (got_gl_error ("glTexImage2D"))
|
||||
goto mem_error;
|
||||
|
||||
image =
|
||||
gst_egl_display_image_create (display,
|
||||
eglcontext, EGL_GL_TEXTURE_2D_KHR,
|
||||
(EGLClientBuffer) (uintptr_t) data->texture, NULL);
|
||||
if (got_egl_error ("eglCreateImageKHR"))
|
||||
goto mem_error;
|
||||
|
||||
mem[i] =
|
||||
gst_egl_image_allocator_wrap (allocator, display,
|
||||
image,
|
||||
(i ==
|
||||
0 ? GST_VIDEO_GL_TEXTURE_TYPE_LUMINANCE :
|
||||
GST_VIDEO_GL_TEXTURE_TYPE_LUMINANCE_ALPHA),
|
||||
flags, size[i], data,
|
||||
(GDestroyNotify) gst_egl_gles_image_data_free);
|
||||
}
|
||||
|
||||
n_mem = 2;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case GST_VIDEO_FORMAT_I420:
|
||||
case GST_VIDEO_FORMAT_YV12:
|
||||
case GST_VIDEO_FORMAT_Y444:
|
||||
case GST_VIDEO_FORMAT_Y42B:
|
||||
case GST_VIDEO_FORMAT_Y41B:{
|
||||
EGLImageKHR image;
|
||||
gsize size[3];
|
||||
|
||||
mem[0] =
|
||||
gst_egl_image_allocator_alloc (allocator, display,
|
||||
GST_VIDEO_GL_TEXTURE_TYPE_LUMINANCE, GST_VIDEO_INFO_COMP_WIDTH (&info,
|
||||
0), GST_VIDEO_INFO_COMP_HEIGHT (&info, 0), &size[0]);
|
||||
mem[1] =
|
||||
gst_egl_image_allocator_alloc (allocator, display,
|
||||
GST_VIDEO_GL_TEXTURE_TYPE_LUMINANCE, GST_VIDEO_INFO_COMP_WIDTH (&info,
|
||||
1), GST_VIDEO_INFO_COMP_HEIGHT (&info, 1), &size[1]);
|
||||
mem[2] =
|
||||
gst_egl_image_allocator_alloc (allocator, display,
|
||||
GST_VIDEO_GL_TEXTURE_TYPE_LUMINANCE, GST_VIDEO_INFO_COMP_WIDTH (&info,
|
||||
2), GST_VIDEO_INFO_COMP_HEIGHT (&info, 2), &size[2]);
|
||||
|
||||
if (mem[0] && mem[1] && mem[2]) {
|
||||
stride[0] = size[0] / GST_VIDEO_INFO_HEIGHT (&info);
|
||||
offset[1] = size[0];
|
||||
stride[1] = size[1] / GST_VIDEO_INFO_HEIGHT (&info);
|
||||
offset[2] = size[1];
|
||||
stride[2] = size[2] / GST_VIDEO_INFO_HEIGHT (&info);
|
||||
n_mem = 3;
|
||||
GST_MINI_OBJECT_FLAG_SET (mem[0], GST_MEMORY_FLAG_NO_SHARE);
|
||||
GST_MINI_OBJECT_FLAG_SET (mem[1], GST_MEMORY_FLAG_NO_SHARE);
|
||||
GST_MINI_OBJECT_FLAG_SET (mem[2], GST_MEMORY_FLAG_NO_SHARE);
|
||||
} else {
|
||||
if (mem[0])
|
||||
gst_memory_unref (mem[0]);
|
||||
if (mem[1])
|
||||
gst_memory_unref (mem[1]);
|
||||
if (mem[2])
|
||||
gst_memory_unref (mem[2]);
|
||||
mem[0] = mem[1] = mem[2] = NULL;
|
||||
|
||||
stride[0] = GST_ROUND_UP_4 (GST_VIDEO_INFO_COMP_WIDTH (&info, 0));
|
||||
stride[1] = GST_ROUND_UP_4 (GST_VIDEO_INFO_COMP_WIDTH (&info, 1));
|
||||
stride[2] = GST_ROUND_UP_4 (GST_VIDEO_INFO_COMP_WIDTH (&info, 2));
|
||||
size[0] = stride[0] * GST_VIDEO_INFO_COMP_HEIGHT (&info, 0);
|
||||
size[1] = stride[1] * GST_VIDEO_INFO_COMP_HEIGHT (&info, 1);
|
||||
size[2] = stride[2] * GST_VIDEO_INFO_COMP_HEIGHT (&info, 2);
|
||||
offset[0] = 0;
|
||||
offset[1] = size[0];
|
||||
offset[2] = offset[1] + size[1];
|
||||
|
||||
for (i = 0; i < 3; i++) {
|
||||
data = g_slice_new0 (GstEGLGLESImageData);
|
||||
data->display = gst_egl_display_get (display);
|
||||
data->eglcontext = eglcontext;
|
||||
|
||||
glGenTextures (1, &data->texture);
|
||||
if (got_gl_error ("glGenTextures"))
|
||||
goto mem_error;
|
||||
|
||||
glBindTexture (GL_TEXTURE_2D, data->texture);
|
||||
if (got_gl_error ("glBindTexture"))
|
||||
goto mem_error;
|
||||
|
||||
/* Set 2D resizing params */
|
||||
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
|
||||
/* If these are not set the texture image unit will return
|
||||
* * (R, G, B, A) = black on glTexImage2D for non-POT width/height
|
||||
* * frames. For a deeper explanation take a look at the OpenGL ES
|
||||
* * documentation for glTexParameter */
|
||||
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
if (got_gl_error ("glTexParameteri"))
|
||||
goto mem_error;
|
||||
|
||||
glTexImage2D (GL_TEXTURE_2D, 0, GL_LUMINANCE,
|
||||
GST_VIDEO_INFO_COMP_WIDTH (&info, i),
|
||||
GST_VIDEO_INFO_COMP_HEIGHT (&info, i), 0, GL_LUMINANCE,
|
||||
GL_UNSIGNED_BYTE, NULL);
|
||||
|
||||
if (got_gl_error ("glTexImage2D"))
|
||||
goto mem_error;
|
||||
|
||||
image =
|
||||
gst_egl_display_image_create (display,
|
||||
eglcontext, EGL_GL_TEXTURE_2D_KHR,
|
||||
(EGLClientBuffer) (uintptr_t) data->texture, NULL);
|
||||
if (got_egl_error ("eglCreateImageKHR"))
|
||||
goto mem_error;
|
||||
|
||||
mem[i] =
|
||||
gst_egl_image_allocator_wrap (allocator, display,
|
||||
image, GST_VIDEO_GL_TEXTURE_TYPE_LUMINANCE,
|
||||
flags, size[i], data,
|
||||
(GDestroyNotify) gst_egl_gles_image_data_free);
|
||||
}
|
||||
|
||||
n_mem = 3;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case GST_VIDEO_FORMAT_RGBA:
|
||||
case GST_VIDEO_FORMAT_BGRA:
|
||||
case GST_VIDEO_FORMAT_ARGB:
|
||||
case GST_VIDEO_FORMAT_ABGR:
|
||||
case GST_VIDEO_FORMAT_RGBx:
|
||||
case GST_VIDEO_FORMAT_BGRx:
|
||||
case GST_VIDEO_FORMAT_xRGB:
|
||||
case GST_VIDEO_FORMAT_xBGR:
|
||||
case GST_VIDEO_FORMAT_AYUV:{
|
||||
gsize size;
|
||||
EGLImageKHR image;
|
||||
|
||||
mem[0] =
|
||||
gst_egl_image_allocator_alloc (allocator, display,
|
||||
GST_VIDEO_GL_TEXTURE_TYPE_RGBA, GST_VIDEO_INFO_WIDTH (&info),
|
||||
GST_VIDEO_INFO_HEIGHT (&info), &size);
|
||||
if (mem[0]) {
|
||||
stride[0] = size / GST_VIDEO_INFO_HEIGHT (&info);
|
||||
n_mem = 1;
|
||||
GST_MINI_OBJECT_FLAG_SET (mem[0], GST_MEMORY_FLAG_NO_SHARE);
|
||||
} else {
|
||||
data = g_slice_new0 (GstEGLGLESImageData);
|
||||
data->display = gst_egl_display_get (display);
|
||||
data->eglcontext = eglcontext;
|
||||
|
||||
stride[0] = GST_ROUND_UP_4 (GST_VIDEO_INFO_WIDTH (&info) * 4);
|
||||
size = stride[0] * GST_VIDEO_INFO_HEIGHT (&info);
|
||||
|
||||
glGenTextures (1, &data->texture);
|
||||
if (got_gl_error ("glGenTextures"))
|
||||
goto mem_error;
|
||||
|
||||
glBindTexture (GL_TEXTURE_2D, data->texture);
|
||||
if (got_gl_error ("glBindTexture"))
|
||||
goto mem_error;
|
||||
|
||||
/* Set 2D resizing params */
|
||||
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
|
||||
/* If these are not set the texture image unit will return
|
||||
* * (R, G, B, A) = black on glTexImage2D for non-POT width/height
|
||||
* * frames. For a deeper explanation take a look at the OpenGL ES
|
||||
* * documentation for glTexParameter */
|
||||
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
if (got_gl_error ("glTexParameteri"))
|
||||
goto mem_error;
|
||||
|
||||
glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA,
|
||||
GST_VIDEO_INFO_WIDTH (&info),
|
||||
GST_VIDEO_INFO_HEIGHT (&info), 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
|
||||
if (got_gl_error ("glTexImage2D"))
|
||||
goto mem_error;
|
||||
|
||||
image =
|
||||
gst_egl_display_image_create (display,
|
||||
eglcontext, EGL_GL_TEXTURE_2D_KHR,
|
||||
(EGLClientBuffer) (uintptr_t) data->texture, NULL);
|
||||
if (got_egl_error ("eglCreateImageKHR"))
|
||||
goto mem_error;
|
||||
|
||||
mem[0] =
|
||||
gst_egl_image_allocator_wrap (allocator, display,
|
||||
image, GST_VIDEO_GL_TEXTURE_TYPE_RGBA,
|
||||
flags, size, data, (GDestroyNotify) gst_egl_gles_image_data_free);
|
||||
|
||||
n_mem = 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
break;
|
||||
}
|
||||
|
||||
buffer = gst_buffer_new ();
|
||||
gst_buffer_add_video_meta_full (buffer, 0, format, width, height,
|
||||
GST_VIDEO_INFO_N_PLANES (&info), offset, stride);
|
||||
|
||||
for (i = 0; i < n_mem; i++)
|
||||
gst_buffer_append_memory (buffer, mem[i]);
|
||||
|
||||
return buffer;
|
||||
|
||||
mem_error:
|
||||
{
|
||||
GST_ERROR_OBJECT (GST_CAT_DEFAULT, "Failed to create EGLImage");
|
||||
|
||||
if (data)
|
||||
gst_egl_gles_image_data_free (data);
|
||||
|
||||
if (mem[0])
|
||||
gst_memory_unref (mem[0]);
|
||||
if (mem[1])
|
||||
gst_memory_unref (mem[1]);
|
||||
if (mem[2])
|
||||
gst_memory_unref (mem[2]);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
gst_egl_adaptation_destroy_native_window (GstEglAdaptationContext * ctx,
|
||||
gpointer * own_window_data, gchar* winsys)
|
||||
{
|
||||
#ifdef USE_EGL_WAYLAND
|
||||
if (g_strcmp0(winsys, "wayland") == 0) {
|
||||
platform_destroy_native_window_wayland (gst_egl_display_get
|
||||
(ctx->display), ctx->used_window, own_window_data);
|
||||
platform_destroy_display_wayland();
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef USE_EGL_X11
|
||||
if (g_strcmp0(winsys, "x11") == 0) {
|
||||
platform_destroy_native_window_x11 (gst_egl_display_get
|
||||
(ctx->display), ctx->used_window, own_window_data);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
gboolean
|
||||
gst_egl_adaptation_create_native_window (GstEglAdaptationContext * ctx,
|
||||
gint width, gint height, gpointer * own_window_data, gchar* winsys)
|
||||
{
|
||||
GstEglGlesSink *sink = (GstEglGlesSink *) ctx->element;
|
||||
EGLNativeWindowType window = NULL;
|
||||
|
||||
#ifdef USE_EGL_WAYLAND
|
||||
if (g_strcmp0(winsys, "wayland") == 0) {
|
||||
window =
|
||||
platform_create_native_window_wayland (sink->window_x,
|
||||
sink->window_y,
|
||||
width,
|
||||
height,
|
||||
own_window_data);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef USE_EGL_X11
|
||||
if (g_strcmp0(winsys, "x11") == 0) {
|
||||
window =
|
||||
platform_create_native_window_x11 (sink->window_x,
|
||||
sink->window_y,
|
||||
width,
|
||||
height,
|
||||
own_window_data);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (window)
|
||||
gst_egl_adaptation_set_window (ctx, (uintptr_t) window);
|
||||
GST_DEBUG_OBJECT (ctx->element, "Using window handle %p", (gpointer) window);
|
||||
return window != 0;
|
||||
}
|
||||
|
||||
void
|
||||
gst_egl_adaptation_set_window (GstEglAdaptationContext * ctx, guintptr window)
|
||||
{
|
||||
ctx->window = (EGLNativeWindowType)(uintptr_t) window;
|
||||
}
|
||||
|
||||
void
|
||||
gst_egl_adaptation_init (GstEglAdaptationContext * ctx)
|
||||
{
|
||||
ctx->eglglesctx = g_new0 (GstEglGlesRenderContext, 1);
|
||||
}
|
||||
|
||||
void
|
||||
gst_egl_adaptation_deinit (GstEglAdaptationContext * ctx)
|
||||
{
|
||||
g_free (ctx->eglglesctx);
|
||||
}
|
||||
|
||||
void
|
||||
gst_egl_adaptation_destroy_surface (GstEglAdaptationContext * ctx)
|
||||
{
|
||||
if (ctx->eglglesctx->surface) {
|
||||
eglDestroySurface (gst_egl_display_get (ctx->display),
|
||||
ctx->eglglesctx->surface);
|
||||
ctx->eglglesctx->surface = NULL;
|
||||
ctx->have_surface = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
gst_egl_adaptation_destroy_context (GstEglAdaptationContext * ctx)
|
||||
{
|
||||
if (ctx->eglglesctx->eglcontext) {
|
||||
eglDestroyContext (gst_egl_display_get (ctx->display),
|
||||
ctx->eglglesctx->eglcontext);
|
||||
ctx->eglglesctx->eglcontext = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
gst_egl_adaptation_release_thread ()
|
||||
{
|
||||
eglReleaseThread ();
|
||||
}
|
||||
3400
gstegl_src/gst-egl/ext/eglgles/gsteglglessink.c
Normal file
3400
gstegl_src/gst-egl/ext/eglgles/gsteglglessink.c
Normal file
File diff suppressed because it is too large
Load Diff
166
gstegl_src/gst-egl/ext/eglgles/gsteglglessink.h
Normal file
166
gstegl_src/gst-egl/ext/eglgles/gsteglglessink.h
Normal file
@@ -0,0 +1,166 @@
|
||||
/*
|
||||
* GStreamer EGL/GLES Sink
|
||||
* Copyright (C) 2012 Collabora Ltd.
|
||||
* @author: Reynaldo H. Verdejo Pinochet <reynaldo@collabora.com>
|
||||
* @author: Sebastian Dröge <sebastian.droege@collabora.co.uk>
|
||||
* Copyright (c) 2015, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef __GST_EGLGLESSINK_H__
|
||||
#define __GST_EGLGLESSINK_H__
|
||||
|
||||
#include <gst/gst.h>
|
||||
#include <gst/video/video.h>
|
||||
#include <gst/video/gstvideosink.h>
|
||||
#include <gst/base/gstdataqueue.h>
|
||||
|
||||
#include <cuda.h>
|
||||
#include <cudaGL.h>
|
||||
#include <cuda_runtime.h>
|
||||
|
||||
#include "gstegladaptation.h"
|
||||
#include "gstegljitter.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
#define GST_TYPE_EGLGLESSINK \
|
||||
(gst_eglglessink_get_type())
|
||||
#define GST_EGLGLESSINK(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_EGLGLESSINK,GstEglGlesSink))
|
||||
#define GST_EGLGLESSINK_CLASS(klass) \
|
||||
(G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_EGLGLESSINK,GstEglGlesSinkClass))
|
||||
#define GST_IS_EGLGLESSINK(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_EGLGLESSINK))
|
||||
#define GST_IS_EGLGLESSINK_CLASS(klass) \
|
||||
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_EGLGLESSINK))
|
||||
|
||||
typedef struct _GstEglGlesSink GstEglGlesSink;
|
||||
typedef struct _GstEglGlesSinkClass GstEglGlesSinkClass;
|
||||
|
||||
/*
|
||||
* GstEglGlesSink:
|
||||
* @format: Caps' video format field
|
||||
* @display_region: Surface region to use as rendering canvas
|
||||
* @sinkcaps: Full set of suported caps
|
||||
* @current_caps: Current caps
|
||||
* @rendering_path: Rendering path (Slow/Fast)
|
||||
* @eglglesctx: Pointer to the associated EGL/GLESv2 rendering context
|
||||
* @flow_lock: Simple concurrent access ward to the sink's runtime state
|
||||
* @have_window: Set if the sink has access to a window to hold it's canvas
|
||||
* @using_own_window: Set if the sink created its own window
|
||||
* @egl_started: Set if the whole EGL setup has been performed
|
||||
* @create_window: Property value holder to allow/forbid internal window creation
|
||||
* @force_rendering_slow: Property value holder to force slow rendering path
|
||||
* @force_aspect_ratio: Property value holder to consider PAR/DAR when scaling
|
||||
*
|
||||
* The #GstEglGlesSink data structure.
|
||||
*/
|
||||
struct _GstEglGlesSink
|
||||
{
|
||||
GstVideoSink videosink; /* Element hook */
|
||||
|
||||
/* Region of the surface that should be rendered */
|
||||
GstVideoRectangle render_region;
|
||||
gboolean render_region_changed;
|
||||
gboolean render_region_user;
|
||||
|
||||
/* Region of render_region that should be filled
|
||||
* with the video frames */
|
||||
GstVideoRectangle display_region;
|
||||
|
||||
GstVideoRectangle crop;
|
||||
gboolean crop_changed;
|
||||
GstCaps *sinkcaps;
|
||||
GstCaps *current_caps, *configured_caps;
|
||||
GstVideoInfo configured_info;
|
||||
gfloat stride[3];
|
||||
GstVideoGLTextureOrientation orientation;
|
||||
#ifndef HAVE_IOS
|
||||
GstBufferPool *pool;
|
||||
#endif
|
||||
|
||||
GstEglAdaptationContext *egl_context;
|
||||
gint window_x;
|
||||
gint window_y;
|
||||
gint window_width;
|
||||
gint window_height;
|
||||
guint profile;
|
||||
gint rows;
|
||||
gint columns;
|
||||
gint change_port;
|
||||
|
||||
/* Runtime flags */
|
||||
gboolean have_window;
|
||||
gboolean using_own_window;
|
||||
gboolean egl_started;
|
||||
gboolean is_reconfiguring;
|
||||
gboolean is_closing;
|
||||
gboolean using_cuda;
|
||||
|
||||
gpointer own_window_data;
|
||||
GMutex window_lock;
|
||||
|
||||
GThread *thread;
|
||||
gboolean thread_running;
|
||||
GstDataQueue *queue;
|
||||
GCond render_exit_cond;
|
||||
GCond render_cond;
|
||||
GMutex render_lock;
|
||||
GstFlowReturn last_flow;
|
||||
GstMiniObject *dequeued_object;
|
||||
GThread *event_thread;
|
||||
|
||||
GstBuffer *last_buffer;
|
||||
|
||||
EGLNativeDisplayType display;
|
||||
|
||||
GstEglJitterTool *pDeliveryJitter;
|
||||
|
||||
/* Properties */
|
||||
gboolean create_window;
|
||||
gboolean force_aspect_ratio;
|
||||
gchar* winsys;
|
||||
|
||||
PFNGLEGLIMAGETARGETTEXTURE2DOESPROC glEGLImageTargetTexture2DOES;
|
||||
|
||||
GstBuffer *last_uploaded_buffer;
|
||||
CUcontext cuContext;
|
||||
CUgraphicsResource cuResource[3];
|
||||
unsigned int gpu_id;
|
||||
gboolean nvbuf_api_version_new;
|
||||
|
||||
/*
|
||||
Pointer to a SW Buffer. This is needed in case of RGB/BGR as Cuda
|
||||
doesn't support 3-channel formats. The cuda buffer (host or device)
|
||||
is copied using cuMemCpy2D into this sw buffer and then fill the GL
|
||||
texture from the SW buffer.
|
||||
*/
|
||||
uint8_t *swData;
|
||||
};
|
||||
|
||||
struct _GstEglGlesSinkClass
|
||||
{
|
||||
GstVideoSinkClass parent_class;
|
||||
};
|
||||
|
||||
GType gst_eglglessink_get_type (void);
|
||||
|
||||
G_END_DECLS
|
||||
#endif /* __GST_EGLGLESSINK_H__ */
|
||||
158
gstegl_src/gst-egl/ext/eglgles/gstegljitter.c
Normal file
158
gstegl_src/gst-egl/ext/eglgles/gstegljitter.c
Normal file
@@ -0,0 +1,158 @@
|
||||
/* Copyright (c) 2008 NVIDIA Corporation. All rights reserved.
|
||||
*
|
||||
* NVIDIA Corporation and its licensors retain all intellectual property
|
||||
* and proprietary rights in and to this software, related documentation
|
||||
* and any modifications thereto. Any use, reproduction, disclosure or
|
||||
* distribution of this software and related documentation without an
|
||||
* express license agreement from NVIDIA Corporation is strictly prohibited.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#include "gstegljitter.h"
|
||||
|
||||
GstEglJitterTool *GstEglAllocJitterTool(const char *pName, guint nTicks)
|
||||
{
|
||||
GstEglJitterTool *pTool;
|
||||
|
||||
assert(pName);
|
||||
assert(nTicks > 0);
|
||||
|
||||
pTool = malloc(sizeof(GstEglJitterTool));
|
||||
if (!pTool)
|
||||
return NULL;
|
||||
|
||||
memset(pTool, 0, sizeof(GstEglJitterTool));
|
||||
pTool->pName = malloc(strlen(pName) + 1);
|
||||
if (!pTool->pName)
|
||||
{
|
||||
free(pTool);
|
||||
return NULL;
|
||||
}
|
||||
memcpy((char *)pTool->pName, pName, strlen(pName) + 1);
|
||||
|
||||
pTool->pTicks = malloc(sizeof(guint64) * nTicks);
|
||||
if (!pTool->pTicks)
|
||||
{
|
||||
free(pTool->pName);
|
||||
free(pTool);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pTool->nTicksMax = nTicks;
|
||||
pTool->nTickCount = 0;
|
||||
pTool->nLastTime = 0;
|
||||
pTool->bShow = 0;
|
||||
|
||||
return pTool;
|
||||
}
|
||||
|
||||
void GstEglFreeJitterTool(GstEglJitterTool *pTool)
|
||||
{
|
||||
if (!pTool)
|
||||
return;
|
||||
free(pTool->pName);
|
||||
free(pTool->pTicks);
|
||||
free(pTool);
|
||||
}
|
||||
|
||||
void GstEglJitterToolAddPoint(GstEglJitterTool *pTool)
|
||||
{
|
||||
guint64 now;
|
||||
assert(pTool);
|
||||
|
||||
static guint64 s_oldtime = 0;
|
||||
static guint64 s_timedelta = 0;
|
||||
struct timeval tv;
|
||||
guint64 time;
|
||||
|
||||
(void)gettimeofday( &tv, 0 );
|
||||
time = (guint64)( ( (guint64)tv.tv_sec * 1000 * 1000 ) + (guint64)tv.tv_usec );
|
||||
if (time < s_oldtime)
|
||||
s_timedelta += (s_oldtime - time);
|
||||
s_oldtime = time;
|
||||
time += s_timedelta;
|
||||
|
||||
now = time;
|
||||
|
||||
if (pTool->nLastTime == 0)
|
||||
{
|
||||
pTool->nLastTime = now;
|
||||
return;
|
||||
}
|
||||
|
||||
pTool->pTicks[pTool->nTickCount] = now - pTool->nLastTime;
|
||||
pTool->nLastTime = now;
|
||||
pTool->nTickCount++;
|
||||
|
||||
if (pTool->nTickCount < pTool->nTicksMax)
|
||||
return;
|
||||
|
||||
{
|
||||
double fAvg = 0;
|
||||
double fStdDev = 0;
|
||||
guint i;
|
||||
|
||||
for (i = 0; i < pTool->nTicksMax; i++)
|
||||
fAvg += pTool->pTicks[i];
|
||||
fAvg /= pTool->nTicksMax;
|
||||
|
||||
for (i = 0; i < pTool->nTicksMax; i++)
|
||||
fStdDev += (fAvg - pTool->pTicks[i]) * (fAvg - pTool->pTicks[i]);
|
||||
fStdDev = sqrt(fStdDev / (pTool->nTicksMax - 1));
|
||||
|
||||
if (pTool->bShow)
|
||||
printf("%s: mean: %.2f std. dev: %.2f\n", pTool->pName,
|
||||
fAvg, fStdDev);
|
||||
|
||||
if (pTool->nPos < MAX_JITTER_HISTORY)
|
||||
{
|
||||
pTool->fAvg[pTool->nPos] = fAvg;
|
||||
pTool->fStdDev[pTool->nPos] = fStdDev;
|
||||
pTool->nPos++;
|
||||
}
|
||||
}
|
||||
|
||||
pTool->nTickCount = 0;
|
||||
}
|
||||
|
||||
void GstEglJitterToolSetShow(GstEglJitterTool *pTool, gboolean bShow)
|
||||
{
|
||||
pTool->bShow = bShow;
|
||||
}
|
||||
|
||||
void GstEglJitterToolGetAvgs(GstEglJitterTool *pTool, double *pStdDev, double *pAvg,
|
||||
double *pHighest)
|
||||
{
|
||||
guint i;
|
||||
|
||||
assert(pTool);
|
||||
assert(pStdDev);
|
||||
assert(pAvg);
|
||||
assert(pHighest);
|
||||
|
||||
*pStdDev = 0;
|
||||
*pAvg = 0;
|
||||
*pHighest = 0;
|
||||
|
||||
if (pTool->nPos < 1)
|
||||
return;
|
||||
|
||||
for (i = 1; i < pTool->nPos && i < MAX_JITTER_HISTORY; i++)
|
||||
{
|
||||
*pAvg = *pAvg + pTool->fAvg[i];
|
||||
*pStdDev = *pStdDev + pTool->fStdDev[i];
|
||||
|
||||
if (pTool->fStdDev[i] > *pHighest)
|
||||
*pHighest = pTool->fStdDev[i];
|
||||
}
|
||||
|
||||
*pAvg = *pAvg / (pTool->nPos);
|
||||
*pStdDev = *pStdDev / (pTool->nPos);
|
||||
}
|
||||
|
||||
43
gstegl_src/gst-egl/ext/eglgles/gstegljitter.h
Normal file
43
gstegl_src/gst-egl/ext/eglgles/gstegljitter.h
Normal file
@@ -0,0 +1,43 @@
|
||||
/* Copyright (c) 2008 NVIDIA Corporation. All rights reserved.
|
||||
*
|
||||
* NVIDIA Corporation and its licensors retain all intellectual property
|
||||
* and proprietary rights in and to this software, related documentation
|
||||
* and any modifications thereto. Any use, reproduction, disclosure or
|
||||
* distribution of this software and related documentation without an
|
||||
* express license agreement from NVIDIA Corporation is strictly prohibited.
|
||||
*/
|
||||
|
||||
#ifndef NVXJITTER_H_
|
||||
#define NVXJITTER_H_
|
||||
|
||||
#include <gst/gst.h>
|
||||
#include <stdio.h>
|
||||
|
||||
typedef struct GstEglJitterTool
|
||||
{
|
||||
gchar *pName;
|
||||
guint64 *pTicks;
|
||||
guint nTicksMax;
|
||||
guint nTickCount;
|
||||
|
||||
guint64 nLastTime;
|
||||
|
||||
gboolean bShow;
|
||||
|
||||
#define MAX_JITTER_HISTORY 3000
|
||||
double fAvg[MAX_JITTER_HISTORY];
|
||||
double fStdDev[MAX_JITTER_HISTORY];
|
||||
guint nPos;
|
||||
} GstEglJitterTool;
|
||||
|
||||
GstEglJitterTool *GstEglAllocJitterTool(const char *pName, guint nTicks);
|
||||
void GstEglFreeJitterTool(GstEglJitterTool *pTool);
|
||||
|
||||
void GstEglJitterToolAddPoint(GstEglJitterTool *pTool);
|
||||
void GstEglJitterToolSetShow(GstEglJitterTool *pTool, gboolean bShow);
|
||||
|
||||
void GstEglJitterToolGetAvgs(GstEglJitterTool *pTool, double *pStdDev, double *pAvg,
|
||||
double *pHighest);
|
||||
|
||||
#endif
|
||||
|
||||
834
gstegl_src/gst-egl/ext/eglgles/video_platform_wrapper.c
Normal file
834
gstegl_src/gst-egl/ext/eglgles/video_platform_wrapper.c
Normal file
@@ -0,0 +1,834 @@
|
||||
/*
|
||||
* GStreamer Android Video Platform Wrapper
|
||||
* Copyright (C) 2012 Collabora Ltd.
|
||||
* @author: Reynaldo H. Verdejo Pinochet <reynaldo@collabora.com>
|
||||
* Copyright (c) 2014-2015, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#if defined (USE_EGL_RPI) && defined(__GNUC__)
|
||||
#ifndef __VCCOREVER__
|
||||
#define __VCCOREVER__ 0x04000000
|
||||
#endif
|
||||
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wredundant-decls"
|
||||
#pragma GCC optimize ("gnu89-inline")
|
||||
#endif
|
||||
|
||||
#define EGL_EGLEXT_PROTOTYPES
|
||||
#define GL_GLEXT_PROTOTYPES
|
||||
#include <EGL/egl.h>
|
||||
#include <EGL/eglext.h>
|
||||
#include <GLES2/gl2.h>
|
||||
#include <GLES2/gl2ext.h>
|
||||
|
||||
#if defined (USE_EGL_RPI) && defined(__GNUC__)
|
||||
#pragma GCC reset_options
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <gst/gst.h>
|
||||
#include "video_platform_wrapper.h"
|
||||
|
||||
GST_DEBUG_CATEGORY_STATIC (eglgles_platform_wrapper);
|
||||
#define GST_CAT_DEFAULT eglgles_platform_wrapper
|
||||
|
||||
/* XXX: Likely to be removed */
|
||||
gboolean
|
||||
platform_wrapper_init (void)
|
||||
{
|
||||
GST_DEBUG_CATEGORY_INIT (eglgles_platform_wrapper,
|
||||
"eglglessink-platform", 0,
|
||||
"Platform dependent native-window utility routines for EglGles");
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#ifdef USE_EGL_X11
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xutil.h>
|
||||
|
||||
EGLNativeWindowType
|
||||
platform_create_native_window_x11 (gint x, gint y, gint width, gint height, gpointer * window_data)
|
||||
{
|
||||
Display *d;
|
||||
Window w;
|
||||
int s;
|
||||
X11WindowData *data;
|
||||
const gchar *app_name;
|
||||
XSizeHints hints = {0};
|
||||
hints.flags = PPosition ;
|
||||
hints.x = x;
|
||||
hints.y = y;
|
||||
|
||||
d = XOpenDisplay (NULL);
|
||||
if (d == NULL) {
|
||||
GST_ERROR ("Can't open X11 display");
|
||||
return (EGLNativeWindowType) 0;
|
||||
}
|
||||
|
||||
s = DefaultScreen (d);
|
||||
w = XCreateSimpleWindow (d, RootWindow (d, s), hints.x, hints.y, width, height, 1,
|
||||
BlackPixel (d, s), WhitePixel (d, s));
|
||||
|
||||
/* Prevent X from redrawing the background on ConfigureNotify.
|
||||
Otherwise flickering is observed when resizing the window. */
|
||||
XSetWindowBackgroundPixmap (d, w, None);
|
||||
|
||||
/* set application name as a title */
|
||||
app_name = g_get_application_name ();
|
||||
if (!app_name)
|
||||
app_name = "eglglessink";
|
||||
XStoreName (d, w, app_name);
|
||||
|
||||
XSetNormalHints(d, w, &hints);
|
||||
XMapWindow (d, w);
|
||||
|
||||
Atom wmDeleteMessage = XInternAtom (d, "WM_DELETE_WINDOW", False);
|
||||
if (wmDeleteMessage != None) {
|
||||
XSetWMProtocols (d, w, &wmDeleteMessage, 1);
|
||||
}
|
||||
|
||||
XFlush (d);
|
||||
|
||||
*window_data = data = g_slice_new0 (X11WindowData);
|
||||
data->display = d;
|
||||
|
||||
return (EGLNativeWindowType) w;
|
||||
}
|
||||
|
||||
gboolean
|
||||
platform_destroy_native_window_x11 (EGLNativeDisplayType display,
|
||||
EGLNativeWindowType window, gpointer * window_data)
|
||||
{
|
||||
X11WindowData *data = *window_data;
|
||||
|
||||
/* XXX: Should proly catch BadWindow */
|
||||
XDestroyWindow (data->display, (Window) window);
|
||||
XSync (data->display, FALSE);
|
||||
XCloseDisplay (data->display);
|
||||
|
||||
g_slice_free (X11WindowData, data);
|
||||
*window_data = NULL;
|
||||
return TRUE;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if USE_EGL_WAYLAND
|
||||
|
||||
WaylandDisplay *wayland_display;
|
||||
volatile gint instance_count = 0;
|
||||
|
||||
void global_registry_handler (void *data, struct wl_registry *registry, uint32_t id,
|
||||
const char *interface, uint32_t version);
|
||||
void global_registry_remover (void *data, struct wl_registry *registry, uint32_t id);
|
||||
|
||||
void global_registry_handler (void *data, struct wl_registry *registry, uint32_t id,
|
||||
const char *interface, uint32_t version)
|
||||
{
|
||||
if (strcmp (interface, "wl_compositor") == 0) {
|
||||
wayland_display->compositor = wl_registry_bind (registry,
|
||||
id,
|
||||
&wl_compositor_interface,
|
||||
1);
|
||||
}
|
||||
else if (strcmp (interface, "wl_shell") == 0) {
|
||||
wayland_display->shell = wl_registry_bind (registry, id,
|
||||
&wl_shell_interface, 1);
|
||||
}
|
||||
}
|
||||
|
||||
void global_registry_remover (void *data, struct wl_registry *registry, uint32_t id)
|
||||
{
|
||||
}
|
||||
|
||||
const struct wl_registry_listener registry_listener = {
|
||||
global_registry_handler,
|
||||
global_registry_remover
|
||||
};
|
||||
|
||||
EGLNativeDisplayType platform_initialize_display_wayland (void)
|
||||
{
|
||||
wayland_display = g_slice_new0 (WaylandDisplay);
|
||||
wayland_display->display = wl_display_connect (NULL);
|
||||
if (wayland_display->display == NULL) {
|
||||
GST_ERROR ("Can't connect to display");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
wayland_display->registry = wl_display_get_registry (wayland_display->display);
|
||||
|
||||
wl_registry_add_listener (wayland_display->registry, ®istry_listener, NULL);
|
||||
|
||||
wl_display_dispatch (wayland_display->display);
|
||||
wl_display_roundtrip (wayland_display->display);
|
||||
|
||||
if (wayland_display->compositor == NULL || wayland_display->shell == NULL) {
|
||||
GST_ERROR ("Can't find compositor or shell");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return (EGLNativeDisplayType) wayland_display->display;
|
||||
}
|
||||
|
||||
EGLNativeWindowType
|
||||
platform_create_native_window_wayland (gint x, gint y, gint width, gint height, gpointer * window_data)
|
||||
{
|
||||
WaylandWindowData *data;
|
||||
*window_data = data = g_slice_new0 (WaylandWindowData);
|
||||
|
||||
data->surface = wl_compositor_create_surface (wayland_display->compositor);
|
||||
if (data->surface == NULL) {
|
||||
GST_ERROR ("Can't create surface");
|
||||
return (EGLNativeWindowType) 0;
|
||||
}
|
||||
|
||||
data->shell_surface = wl_shell_get_shell_surface (wayland_display->shell, data->surface);
|
||||
wl_shell_surface_set_toplevel (data->shell_surface);
|
||||
|
||||
data->egl_window = wl_egl_window_create (data->surface, width, height);
|
||||
|
||||
g_atomic_int_add(&instance_count, 1);
|
||||
|
||||
return (EGLNativeWindowType) data->egl_window;
|
||||
}
|
||||
|
||||
gboolean platform_destroy_display_wayland (void)
|
||||
{
|
||||
if (g_atomic_int_compare_and_exchange(&instance_count, 0, 0)) {
|
||||
if (wayland_display->compositor) {
|
||||
wl_compositor_destroy (wayland_display->compositor);
|
||||
wayland_display->compositor = NULL;
|
||||
}
|
||||
if (wayland_display->shell) {
|
||||
wayland_display->shell = NULL;
|
||||
}
|
||||
if (wayland_display->registry) {
|
||||
wl_registry_destroy (wayland_display->registry);
|
||||
wayland_display->registry = NULL;
|
||||
}
|
||||
if (wayland_display->display) {
|
||||
wl_display_flush (wayland_display->display);
|
||||
wl_display_disconnect (wayland_display->display);
|
||||
wayland_display->display = NULL;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
gboolean platform_destroy_native_window_wayland (EGLNativeDisplayType display,
|
||||
EGLNativeWindowType window, gpointer * window_data)
|
||||
{
|
||||
WaylandWindowData *data = *window_data;
|
||||
|
||||
if (data->egl_window) {
|
||||
data->egl_window = NULL;
|
||||
}
|
||||
|
||||
if (data->shell_surface) {
|
||||
data->shell_surface = NULL;
|
||||
}
|
||||
|
||||
if (data->surface) {
|
||||
data->surface = NULL;
|
||||
}
|
||||
|
||||
g_atomic_int_add(&instance_count, -1);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef USE_EGL_MALI_FB
|
||||
#include <EGL/fbdev_window.h>
|
||||
|
||||
EGLNativeWindowType
|
||||
platform_create_native_window (gint x, gint y, gint width, gint height, gpointer * window_data)
|
||||
{
|
||||
fbdev_window *w = g_slice_new0 (fbdev_window);
|
||||
|
||||
w->width = width;
|
||||
w->height = height;
|
||||
|
||||
return (EGLNativeWindowType) w;
|
||||
}
|
||||
|
||||
gboolean
|
||||
platform_destroy_native_window (EGLNativeDisplayType display,
|
||||
EGLNativeWindowType window, gpointer * window_data)
|
||||
{
|
||||
g_slice_free (fbdev_window, ((fbdev_window *) window));
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* FIXME: Move to gst-libs/gst/egl */
|
||||
#if 0
|
||||
#include <mali_egl_image.h>
|
||||
#include <ump/ump.h>
|
||||
#include <ump/ump_ref_drv.h>
|
||||
#include <gst/video/video.h>
|
||||
static gpointer
|
||||
eglimage_map (GstMemory * gmem, gsize maxsize, GstMapFlags flags)
|
||||
{
|
||||
GstEGLImageMemory *mem;
|
||||
gint i;
|
||||
|
||||
g_return_val_if_fail (strcmp (gmem->allocator->mem_type,
|
||||
GST_EGL_IMAGE_MEMORY_NAME) == 0, FALSE);
|
||||
|
||||
mem = GST_EGL_IMAGE_MEMORY (gmem);
|
||||
|
||||
g_mutex_lock (&mem->lock);
|
||||
for (i = 0; i < mem->n_textures; i++) {
|
||||
if (mem->memory_refcount[i]) {
|
||||
/* Only multiple READ maps are allowed */
|
||||
if ((mem->memory_flags[i] & GST_MAP_WRITE)) {
|
||||
g_mutex_unlock (&mem->lock);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!mem->mapped_memory_refcount) {
|
||||
EGLint attribs[] = {
|
||||
MALI_EGL_IMAGE_PLANE, MALI_EGL_IMAGE_PLANE_Y,
|
||||
MALI_EGL_IMAGE_ACCESS_MODE, MALI_EGL_IMAGE_ACCESS_READ_ONLY,
|
||||
EGL_NONE
|
||||
};
|
||||
GstVideoInfo info;
|
||||
mali_egl_image *mali_egl_image;
|
||||
guint8 *plane_memory, *p;
|
||||
gint stride, h;
|
||||
gint j;
|
||||
|
||||
gst_video_info_set_format (&info, mem->format, mem->width, mem->height);
|
||||
|
||||
mem->mapped_memory = g_malloc (mem->parent.size);
|
||||
|
||||
for (i = 0; i < mem->n_textures; i++) {
|
||||
mali_egl_image = mali_egl_image_lock_ptr (mem->image[i]);
|
||||
if (!mali_egl_image) {
|
||||
g_free (mem->mapped_memory);
|
||||
GST_ERROR ("Failed to lock Mali EGL image: 0x%04x",
|
||||
mali_egl_image_get_error ());
|
||||
g_mutex_unlock (&mem->lock);
|
||||
return NULL;
|
||||
}
|
||||
plane_memory = mali_egl_image_map_buffer (mali_egl_image, attribs);
|
||||
if (!plane_memory) {
|
||||
mali_egl_image_unlock_ptr (mem->image[i]);
|
||||
g_free (mem->mapped_memory);
|
||||
GST_ERROR ("Failed to lock Mali map image: 0x%04x",
|
||||
mali_egl_image_get_error ());
|
||||
g_mutex_unlock (&mem->lock);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
p = ((guint8 *) mem->mapped_memory) + mem->offset[i];
|
||||
stride = mem->stride[i];
|
||||
h = GST_VIDEO_INFO_COMP_HEIGHT (&info, i);
|
||||
for (j = 0; j < h; j++) {
|
||||
memcpy (p, plane_memory, stride);
|
||||
p += mem->stride[i];
|
||||
plane_memory += mem->stride[i];
|
||||
}
|
||||
|
||||
mali_egl_image_unmap_buffer (mem->image[i], attribs);
|
||||
mali_egl_image_unlock_ptr (mem->image[i]);
|
||||
}
|
||||
} else {
|
||||
/* Only multiple READ maps are allowed */
|
||||
if ((mem->mapped_memory_flags & GST_MAP_WRITE)) {
|
||||
g_mutex_unlock (&mem->lock);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
mem->mapped_memory_refcount++;
|
||||
|
||||
g_mutex_unlock (&mem->lock);
|
||||
|
||||
return mem->mapped_memory;
|
||||
}
|
||||
|
||||
static void
|
||||
eglimage_unmap (GstMemory * gmem)
|
||||
{
|
||||
GstEGLImageMemory *mem;
|
||||
gint i;
|
||||
|
||||
g_return_if_fail (strcmp (gmem->allocator->mem_type,
|
||||
GST_EGL_IMAGE_MEMORY_NAME) == 0);
|
||||
|
||||
mem = GST_EGL_IMAGE_MEMORY (gmem);
|
||||
g_return_if_fail (mem->mapped_memory);
|
||||
|
||||
g_mutex_lock (&mem->lock);
|
||||
|
||||
mem->mapped_memory_refcount--;
|
||||
if (mem->mapped_memory_refcount > 0) {
|
||||
g_mutex_unlock (&mem->lock);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Write back */
|
||||
if ((mem->mapped_memory_flags & GST_MAP_WRITE)) {
|
||||
EGLint attribs[] = {
|
||||
MALI_EGL_IMAGE_PLANE, MALI_EGL_IMAGE_PLANE_Y,
|
||||
MALI_EGL_IMAGE_ACCESS_MODE, MALI_EGL_IMAGE_ACCESS_WRITE_ONLY,
|
||||
EGL_NONE
|
||||
};
|
||||
GstVideoInfo info;
|
||||
mali_egl_image *mali_egl_image;
|
||||
guint8 *plane_memory, *p;
|
||||
gint stride, h;
|
||||
gint j;
|
||||
|
||||
gst_video_info_set_format (&info, mem->format, mem->width, mem->height);
|
||||
|
||||
for (i = 0; i < mem->n_textures; i++) {
|
||||
mali_egl_image = mali_egl_image_lock_ptr (mem->image[i]);
|
||||
if (!mali_egl_image) {
|
||||
g_free (mem->mapped_memory);
|
||||
GST_ERROR ("Failed to lock Mali EGL image: 0x%04x",
|
||||
mali_egl_image_get_error ());
|
||||
g_mutex_unlock (&mem->lock);
|
||||
return;
|
||||
}
|
||||
plane_memory = mali_egl_image_map_buffer (mali_egl_image, attribs);
|
||||
if (!plane_memory) {
|
||||
mali_egl_image_unlock_ptr (mem->image[i]);
|
||||
g_free (mem->mapped_memory);
|
||||
GST_ERROR ("Failed to lock Mali map image: 0x%04x",
|
||||
mali_egl_image_get_error ());
|
||||
g_mutex_unlock (&mem->lock);
|
||||
return;
|
||||
}
|
||||
|
||||
p = ((guint8 *) mem->mapped_memory) + mem->offset[i];
|
||||
stride = mem->stride[i];
|
||||
h = GST_VIDEO_INFO_COMP_HEIGHT (&info, i);
|
||||
for (j = 0; j < h; j++) {
|
||||
memcpy (plane_memory, p, stride);
|
||||
p += mem->stride[i];
|
||||
plane_memory += mem->stride[i];
|
||||
}
|
||||
|
||||
mali_egl_image_unmap_buffer (mem->image[i], attribs);
|
||||
mali_egl_image_unlock_ptr (mem->image[i]);
|
||||
}
|
||||
}
|
||||
g_free (mem->mapped_memory);
|
||||
|
||||
g_mutex_unlock (&mem->lock);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
eglimage_video_map (GstVideoMeta * meta, guint plane,
|
||||
GstMapInfo * info, gpointer * data, gint * stride, GstMapFlags flags)
|
||||
{
|
||||
GstMemory *gmem;
|
||||
GstEGLImageMemory *mem;
|
||||
GstVideoInfo vinfo;
|
||||
|
||||
if (gst_buffer_n_memory (meta->buffer) != 1)
|
||||
return default_map_video (meta, plane, info, data, stride, flags);
|
||||
|
||||
gmem = gst_buffer_peek_memory (meta->buffer, 0);
|
||||
if (strcmp (gmem->allocator->mem_type, GST_EGL_IMAGE_MEMORY_NAME) != 0)
|
||||
return default_map_video (meta, plane, info, data, stride, flags);
|
||||
|
||||
mem = GST_EGL_IMAGE_MEMORY ((gmem->parent ? gmem->parent : gmem));
|
||||
|
||||
g_mutex_lock (&mem->lock);
|
||||
if (mem->format == GST_VIDEO_FORMAT_YV12) {
|
||||
if (plane == 1)
|
||||
plane = 2;
|
||||
else if (plane == 2)
|
||||
plane = 1;
|
||||
}
|
||||
|
||||
if (mem->mapped_memory_refcount) {
|
||||
/* Only multiple READ maps are allowed */
|
||||
if ((mem->mapped_memory_flags & GST_MAP_WRITE)) {
|
||||
g_mutex_unlock (&mem->lock);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if (!mem->memory_refcount[plane]) {
|
||||
EGLint attribs[] = {
|
||||
MALI_EGL_IMAGE_PLANE, MALI_EGL_IMAGE_PLANE_Y,
|
||||
MALI_EGL_IMAGE_ACCESS_MODE, MALI_EGL_IMAGE_ACCESS_READ_WRITE,
|
||||
EGL_NONE
|
||||
};
|
||||
|
||||
if ((flags & GST_MAP_READ) && (flags & GST_MAP_WRITE))
|
||||
attribs[3] = MALI_EGL_IMAGE_ACCESS_READ_WRITE;
|
||||
else if ((flags & GST_MAP_READ))
|
||||
attribs[3] = MALI_EGL_IMAGE_ACCESS_READ_ONLY;
|
||||
else if ((flags & GST_MAP_WRITE))
|
||||
attribs[3] = MALI_EGL_IMAGE_ACCESS_WRITE_ONLY;
|
||||
|
||||
mem->memory_platform_data[plane] =
|
||||
mali_egl_image_lock_ptr (mem->image[plane]);
|
||||
if (!mem->memory_platform_data[plane]) {
|
||||
GST_ERROR ("Failed to lock Mali EGL image: 0x%04x",
|
||||
mali_egl_image_get_error ());
|
||||
goto map_error;
|
||||
}
|
||||
|
||||
mem->memory[plane] =
|
||||
mali_egl_image_map_buffer (mem->memory_platform_data[plane], attribs);
|
||||
if (!mem->memory[plane])
|
||||
goto map_error;
|
||||
|
||||
mem->memory_flags[plane] = flags;
|
||||
} else {
|
||||
/* Only multiple READ maps are allowed */
|
||||
if ((mem->memory_flags[plane] & GST_MAP_WRITE)) {
|
||||
g_mutex_unlock (&mem->lock);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
mem->memory_refcount[plane]++;
|
||||
gst_video_info_set_format (&vinfo, mem->format, mem->width, mem->height);
|
||||
|
||||
*data = mem->memory[plane];
|
||||
*stride = mem->stride[plane];
|
||||
|
||||
g_mutex_unlock (&mem->lock);
|
||||
return TRUE;
|
||||
|
||||
map_error:
|
||||
{
|
||||
EGLint attribs[] = {
|
||||
MALI_EGL_IMAGE_PLANE, MALI_EGL_IMAGE_PLANE_Y,
|
||||
EGL_NONE
|
||||
};
|
||||
GST_ERROR ("Failed to map Mali EGL image: 0x%04x",
|
||||
mali_egl_image_get_error ());
|
||||
|
||||
if (mem->memory_platform_data[plane]) {
|
||||
mali_egl_image_unmap_buffer (mem->image[plane], attribs);
|
||||
mali_egl_image_unlock_ptr (mem->image[plane]);
|
||||
}
|
||||
mem->memory[plane] = NULL;
|
||||
mem->memory_platform_data[plane] = NULL;
|
||||
|
||||
g_mutex_unlock (&mem->lock);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
eglimage_video_unmap (GstVideoMeta * meta, guint plane, GstMapInfo * info)
|
||||
{
|
||||
GstMemory *gmem;
|
||||
GstEGLImageMemory *mem;
|
||||
EGLint attribs[] = {
|
||||
MALI_EGL_IMAGE_PLANE, MALI_EGL_IMAGE_PLANE_Y,
|
||||
EGL_NONE
|
||||
};
|
||||
|
||||
if (gst_buffer_n_memory (meta->buffer) != 1)
|
||||
return default_unmap_video (meta, plane, info);
|
||||
|
||||
gmem = gst_buffer_peek_memory (meta->buffer, 0);
|
||||
if (strcmp (gmem->allocator->mem_type, GST_EGL_IMAGE_MEMORY_NAME) != 0)
|
||||
return default_unmap_video (meta, plane, info);
|
||||
|
||||
mem = GST_EGL_IMAGE_MEMORY ((gmem->parent ? gmem->parent : gmem));
|
||||
|
||||
g_mutex_lock (&mem->lock);
|
||||
if (mem->format == GST_VIDEO_FORMAT_YV12) {
|
||||
if (plane == 1)
|
||||
plane = 2;
|
||||
else if (plane == 2)
|
||||
plane = 1;
|
||||
}
|
||||
|
||||
if (!mem->memory_refcount[plane]) {
|
||||
g_mutex_unlock (&mem->lock);
|
||||
g_return_val_if_reached (FALSE);
|
||||
}
|
||||
|
||||
mem->memory_refcount[plane]--;
|
||||
if (mem->memory_refcount[plane] > 0) {
|
||||
g_mutex_unlock (&mem->lock);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* Unmaps automatically */
|
||||
if (mem->memory_platform_data[plane]) {
|
||||
mali_egl_image_unmap_buffer (mem->image[plane], attribs);
|
||||
mali_egl_image_unlock_ptr (mem->image[plane]);
|
||||
}
|
||||
mem->memory[plane] = NULL;
|
||||
mem->memory_platform_data[plane] = NULL;
|
||||
|
||||
g_mutex_unlock (&mem->lock);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
platform_can_map_eglimage (GstMemoryMapFunction * map,
|
||||
GstMemoryUnmapFunction * unmap, PlatformMapVideo * video_map,
|
||||
PlatformUnmapVideo * video_unmap)
|
||||
{
|
||||
*map = eglimage_map;
|
||||
*unmap = eglimage_unmap;
|
||||
*video_map = eglimage_video_map;
|
||||
*video_unmap = eglimage_video_unmap;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
platform_has_custom_eglimage_alloc (void)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
platform_alloc_eglimage (EGLDisplay display, EGLContext context, GLint format,
|
||||
GLint type, gint width, gint height, GLuint tex_id, EGLImageKHR * image,
|
||||
gpointer * image_platform_data)
|
||||
{
|
||||
fbdev_pixmap pixmap;
|
||||
|
||||
pixmap.flags = FBDEV_PIXMAP_SUPPORTS_UMP;
|
||||
pixmap.width = width;
|
||||
pixmap.height = height;
|
||||
|
||||
switch (format) {
|
||||
case GL_LUMINANCE:
|
||||
g_return_val_if_fail (type == GL_UNSIGNED_BYTE, FALSE);
|
||||
pixmap.red_size = 0;
|
||||
pixmap.green_size = 0;
|
||||
pixmap.blue_size = 0;
|
||||
pixmap.alpha_size = 0;
|
||||
pixmap.luminance_size = 8;
|
||||
break;
|
||||
case GL_LUMINANCE_ALPHA:
|
||||
g_return_val_if_fail (type == GL_UNSIGNED_BYTE, FALSE);
|
||||
pixmap.red_size = 0;
|
||||
pixmap.green_size = 0;
|
||||
pixmap.blue_size = 0;
|
||||
pixmap.alpha_size = 8;
|
||||
pixmap.luminance_size = 8;
|
||||
break;
|
||||
case GL_RGB:
|
||||
if (type == GL_UNSIGNED_BYTE) {
|
||||
pixmap.red_size = 8;
|
||||
pixmap.green_size = 8;
|
||||
pixmap.blue_size = 8;
|
||||
pixmap.alpha_size = 0;
|
||||
pixmap.luminance_size = 0;
|
||||
} else if (type == GL_UNSIGNED_SHORT_5_6_5) {
|
||||
pixmap.red_size = 5;
|
||||
pixmap.green_size = 6;
|
||||
pixmap.blue_size = 5;
|
||||
pixmap.alpha_size = 0;
|
||||
pixmap.luminance_size = 0;
|
||||
} else {
|
||||
g_return_val_if_reached (FALSE);
|
||||
}
|
||||
break;
|
||||
case GL_RGBA:
|
||||
g_return_val_if_fail (type == GL_UNSIGNED_BYTE, FALSE);
|
||||
pixmap.red_size = 8;
|
||||
pixmap.green_size = 8;
|
||||
pixmap.blue_size = 8;
|
||||
pixmap.alpha_size = 8;
|
||||
pixmap.luminance_size = 0;
|
||||
break;
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
pixmap.buffer_size =
|
||||
pixmap.red_size + pixmap.green_size + pixmap.blue_size +
|
||||
pixmap.alpha_size + pixmap.luminance_size;
|
||||
pixmap.bytes_per_pixel = pixmap.buffer_size / 8;
|
||||
pixmap.format = 0;
|
||||
|
||||
if (ump_open () != UMP_OK) {
|
||||
GST_ERROR ("Failed to open UMP");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
pixmap.data =
|
||||
ump_ref_drv_allocate (GST_ROUND_UP_4 (pixmap.width) * pixmap.height *
|
||||
pixmap.bytes_per_pixel, UMP_REF_DRV_CONSTRAINT_PHYSICALLY_LINEAR);
|
||||
if (pixmap.data == UMP_INVALID_MEMORY_HANDLE) {
|
||||
GST_ERROR ("Failed to allocate pixmap data via UMP");
|
||||
ump_close ();
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
*image_platform_data = g_slice_dup (fbdev_pixmap, &pixmap);
|
||||
*image =
|
||||
eglCreateImageKHR (display, EGL_NO_CONTEXT, EGL_NATIVE_PIXMAP_KHR,
|
||||
(EGLClientBuffer) * image_platform_data, NULL);
|
||||
if (!image) {
|
||||
GST_ERROR ("Failed to create EGLImage for pixmap");
|
||||
ump_reference_release ((ump_handle) pixmap.data);
|
||||
ump_close ();
|
||||
g_slice_free (fbdev_pixmap, *image_platform_data);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
platform_free_eglimage (EGLDisplay display, EGLContext context, GLuint tex_id,
|
||||
EGLImageKHR * image, gpointer * image_platform_data)
|
||||
{
|
||||
fbdev_pixmap *pixmap = *image_platform_data;
|
||||
|
||||
eglDestroyImageKHR (display, *image);
|
||||
ump_reference_release ((ump_handle) pixmap->data);
|
||||
ump_close ();
|
||||
g_slice_free (fbdev_pixmap, *image_platform_data);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef USE_EGL_RPI
|
||||
#include <bcm_host.h>
|
||||
#include <gst/video/gstvideosink.h>
|
||||
|
||||
typedef struct
|
||||
{
|
||||
EGL_DISPMANX_WINDOW_T w;
|
||||
DISPMANX_DISPLAY_HANDLE_T d;
|
||||
} RPIWindowData;
|
||||
|
||||
EGLNativeWindowType
|
||||
platform_create_native_window (gint x, gint y, gint width, gint height, gpointer * window_data)
|
||||
{
|
||||
DISPMANX_ELEMENT_HANDLE_T dispman_element;
|
||||
DISPMANX_DISPLAY_HANDLE_T dispman_display;
|
||||
DISPMANX_UPDATE_HANDLE_T dispman_update;
|
||||
RPIWindowData *data;
|
||||
VC_RECT_T dst_rect;
|
||||
VC_RECT_T src_rect;
|
||||
GstVideoRectangle src, dst, res;
|
||||
|
||||
uint32_t dp_height;
|
||||
uint32_t dp_width;
|
||||
|
||||
int ret;
|
||||
|
||||
ret = graphics_get_display_size (0, &dp_width, &dp_height);
|
||||
if (ret < 0) {
|
||||
GST_ERROR ("Can't open display");
|
||||
return (EGLNativeWindowType) 0;
|
||||
}
|
||||
GST_DEBUG ("Got display size: %dx%d\n", dp_width, dp_height);
|
||||
GST_DEBUG ("Source size: %dx%d\n", width, height);
|
||||
|
||||
/* Center width*height frame inside dp_width*dp_height */
|
||||
src.w = width;
|
||||
src.h = height;
|
||||
src.x = src.y = 0;
|
||||
dst.w = dp_width;
|
||||
dst.h = dp_height;
|
||||
dst.x = dst.y = 0;
|
||||
gst_video_sink_center_rect (src, dst, &res, TRUE);
|
||||
|
||||
dst_rect.x = res.x;
|
||||
dst_rect.y = res.y;
|
||||
dst_rect.width = res.w;
|
||||
dst_rect.height = res.h;
|
||||
|
||||
src_rect.x = 0;
|
||||
src_rect.y = 0;
|
||||
src_rect.width = width << 16;
|
||||
src_rect.height = height << 16;
|
||||
|
||||
dispman_display = vc_dispmanx_display_open (0);
|
||||
dispman_update = vc_dispmanx_update_start (0);
|
||||
dispman_element = vc_dispmanx_element_add (dispman_update,
|
||||
dispman_display, 0, &dst_rect, 0, &src_rect,
|
||||
DISPMANX_PROTECTION_NONE, 0, 0, 0);
|
||||
|
||||
*window_data = data = g_slice_new0 (RPIWindowData);
|
||||
data->d = dispman_display;
|
||||
data->w.element = dispman_element;
|
||||
data->w.width = width;
|
||||
data->w.height = height;
|
||||
vc_dispmanx_update_submit_sync (dispman_update);
|
||||
|
||||
return (EGLNativeWindowType) data;
|
||||
}
|
||||
|
||||
gboolean
|
||||
platform_destroy_native_window (EGLNativeDisplayType display,
|
||||
EGLNativeWindowType window, gpointer * window_data)
|
||||
{
|
||||
DISPMANX_DISPLAY_HANDLE_T dispman_display;
|
||||
DISPMANX_UPDATE_HANDLE_T dispman_update;
|
||||
RPIWindowData *data = *window_data;
|
||||
|
||||
dispman_display = data->d;
|
||||
dispman_update = vc_dispmanx_update_start (0);
|
||||
vc_dispmanx_element_remove (dispman_update, data->w.element);
|
||||
vc_dispmanx_update_submit_sync (dispman_update);
|
||||
vc_dispmanx_display_close (dispman_display);
|
||||
|
||||
g_slice_free (RPIWindowData, data);
|
||||
*window_data = NULL;
|
||||
return TRUE;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if !defined(USE_EGL_X11) && !defined(USE_EGL_WAYLAND) && !defined(USE_EGL_MALI_FB) && !defined(USE_EGL_RPI)
|
||||
/* Dummy functions for creating a native Window */
|
||||
EGLNativeWindowType
|
||||
platform_create_native_window (gint x, gint y, gint width, gint height, gpointer * window_data)
|
||||
{
|
||||
GST_ERROR ("Can't create native window");
|
||||
return (EGLNativeWindowType) 0;
|
||||
}
|
||||
|
||||
gboolean
|
||||
platform_destroy_native_window (EGLNativeDisplayType display,
|
||||
EGLNativeWindowType window, gpointer * window_data)
|
||||
{
|
||||
GST_ERROR ("Can't destroy native window");
|
||||
return TRUE;
|
||||
}
|
||||
#endif
|
||||
83
gstegl_src/gst-egl/ext/eglgles/video_platform_wrapper.h
Normal file
83
gstegl_src/gst-egl/ext/eglgles/video_platform_wrapper.h
Normal file
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
* GStreamer Android Video Platform Wrapper
|
||||
* Copyright (C) 2012 Collabora Ltd.
|
||||
* @author: Reynaldo H. Verdejo Pinochet <reynaldo@collabora.com>
|
||||
* Copyright (c) 2014-2015, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* General idea is to have all platform dependent code here for easy
|
||||
* tweaking and isolation from the main routines
|
||||
*/
|
||||
|
||||
#ifndef __GST_VIDEO_PLATFORM_WRAPPER__
|
||||
#define __GST_VIDEO_PLATFORM_WRAPPER__
|
||||
|
||||
#include <gst/gst.h>
|
||||
#include <EGL/egl.h>
|
||||
|
||||
#ifdef USE_EGL_X11
|
||||
#include <X11/Xlib.h>
|
||||
typedef struct
|
||||
{
|
||||
Display *display;
|
||||
} X11WindowData;
|
||||
|
||||
EGLNativeWindowType platform_create_native_window_x11 (gint x, gint y, gint width, gint height, gpointer * window_data);
|
||||
gboolean platform_destroy_native_window_x11 (EGLNativeDisplayType display,
|
||||
EGLNativeWindowType w, gpointer * window_data);
|
||||
#endif
|
||||
|
||||
#ifdef USE_EGL_WAYLAND
|
||||
#include <wayland-client.h>
|
||||
#include "wayland-client-protocol.h"
|
||||
#include "wayland-egl.h"
|
||||
typedef struct
|
||||
{
|
||||
struct wl_egl_window *egl_window;
|
||||
struct wl_shell_surface *shell_surface;
|
||||
struct wl_surface *surface;
|
||||
} WaylandWindowData;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
struct wl_display *display;
|
||||
struct wl_compositor *compositor;
|
||||
struct wl_shell *shell;
|
||||
struct wl_registry *registry;
|
||||
} WaylandDisplay;
|
||||
|
||||
EGLNativeWindowType platform_create_native_window_wayland (gint x, gint y, gint width, gint height, gpointer * window_data);
|
||||
EGLNativeDisplayType platform_initialize_display_wayland (void);
|
||||
gboolean platform_destroy_native_window_wayland (EGLNativeDisplayType display,
|
||||
EGLNativeWindowType w, gpointer * window_data);
|
||||
gboolean platform_destroy_display_wayland (void);
|
||||
#endif
|
||||
|
||||
gboolean platform_wrapper_init (void);
|
||||
|
||||
#if !defined(USE_EGL_X11) && !defined(USE_EGL_WAYLAND)
|
||||
EGLNativeWindowType platform_create_native_window (gint x, gint y, gint width, gint height, gpointer * window_data);
|
||||
gboolean platform_destroy_native_window (EGLNativeDisplayType display,
|
||||
EGLNativeWindowType w, gpointer * window_data);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
397
gstegl_src/gst-egl/gst-libs/gst/egl/LICENSE.libgstnvegl-1.0
Normal file
397
gstegl_src/gst-egl/gst-libs/gst/egl/LICENSE.libgstnvegl-1.0
Normal file
@@ -0,0 +1,397 @@
|
||||
The software listed below is licensed under the terms of the LGPLv2
|
||||
(see below). To obtain source code, contact oss-requests@nvidia.com.
|
||||
|
||||
libgstnvegl-1.0.so.0
|
||||
|
||||
------------------------------------
|
||||
|
||||
GNU LIBRARY GENERAL PUBLIC LICENSE
|
||||
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1991 Free Software Foundation, Inc.
|
||||
51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
[This is the first released version of the library GPL. It is
|
||||
numbered 2 because it goes with version 2 of the ordinary GPL.]
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your freedom to share
|
||||
and change it. By contrast, the GNU General Public Licenses are intended to
|
||||
guarantee your freedom to share and change free software--to make sure the
|
||||
software is free for all its users.
|
||||
|
||||
This license, the Library General Public License, applies to some specially
|
||||
designated Free Software Foundation software, and to any other libraries whose
|
||||
authors decide to use it. You can use it for your libraries, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not price. Our
|
||||
General Public Licenses are designed to make sure that you have the freedom to
|
||||
distribute copies of free software (and charge for this service if you wish),
|
||||
that you receive source code or can get it if you want it, that you can change
|
||||
the software or use pieces of it in new free programs; and that you know you can
|
||||
do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid anyone to deny
|
||||
you these rights or to ask you to surrender the rights. These restrictions
|
||||
translate to certain responsibilities for you if you distribute copies of the
|
||||
library, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of the library, whether gratis or for a
|
||||
fee, you must give the recipients all the rights that we gave you. You must make
|
||||
sure that they, too, receive or can get the source code. If you link a program
|
||||
with the library, you must provide complete object files to the recipients so
|
||||
that they can relink them with the library, after making changes to the library
|
||||
and recompiling it. And you must show them these terms so they know their
|
||||
rights.
|
||||
|
||||
Our method of protecting your rights has two steps: (1) copyright the library,
|
||||
and (2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the library.
|
||||
|
||||
Also, for each distributor's protection, we want to make certain that everyone
|
||||
understands that there is no warranty for this free library. If the library is
|
||||
modified by someone else and passed on, we want its recipients to know that what
|
||||
they have is not the original version, so that any problems introduced by others
|
||||
will not reflect on the original authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software patents. We wish
|
||||
to avoid the danger that companies distributing free software will individually
|
||||
obtain patent licenses, thus in effect transforming the program into proprietary
|
||||
software. To prevent this, we have made it clear that any patent must be
|
||||
licensed for everyone's free use or not licensed at all.
|
||||
|
||||
Most GNU software, including some libraries, is covered by the ordinary GNU
|
||||
General Public License, which was designed for utility programs. This license,
|
||||
the GNU Library General Public License, applies to certain designated libraries.
|
||||
This license is quite different from the ordinary one; be sure to read it in
|
||||
full, and don't assume that anything in it is the same as in the ordinary
|
||||
license.
|
||||
|
||||
The reason we have a separate public license for some libraries is that they
|
||||
blur the distinction we usually make between modifying or adding to a program
|
||||
and simply using it. Linking a program with a library, without changing the
|
||||
library, is in some sense simply using the library, and is analogous to running
|
||||
a utility program or application program. However, in a textual and legal sense,
|
||||
the linked executable is a combined work, a derivative of the original library,
|
||||
and the ordinary General Public License treats it as such.
|
||||
|
||||
Because of this blurred distinction, using the ordinary General Public License
|
||||
for libraries did not effectively promote software sharing, because most
|
||||
developers did not use the libraries. We concluded that weaker conditions might
|
||||
promote sharing better.
|
||||
|
||||
However, unrestricted linking of non-free programs would deprive the users of
|
||||
those programs of all benefit from the free status of the libraries themselves.
|
||||
This Library General Public License is intended to permit developers of non-free
|
||||
programs to use free libraries, while preserving your freedom as a user of such
|
||||
programs to change the free libraries that are incorporated in them. (We have
|
||||
not seen how to achieve this as regards changes in header files, but we have
|
||||
achieved it as regards changes in the actual functions of the Library.) The hope
|
||||
is that this will lead to faster development of free libraries.
|
||||
|
||||
The precise terms and conditions for copying, distribution and modification
|
||||
follow. Pay close attention to the difference between a "work based on the
|
||||
library" and a "work that uses the library". The former contains code derived
|
||||
from the library, while the latter only works together with the library.
|
||||
|
||||
Note that it is possible for a library to be covered by the ordinary General
|
||||
Public License rather than by this special one.
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License Agreement applies to any software library which contains a
|
||||
notice placed by the copyright holder or other authorized party saying it may be
|
||||
distributed under the terms of this Library General Public License (also called
|
||||
"this License"). Each licensee is addressed as "you".
|
||||
|
||||
A "library" means a collection of software functions and/or data prepared so as
|
||||
to be conveniently linked with application programs (which use some of those
|
||||
functions and data) to form executables.
|
||||
|
||||
The "Library", below, refers to any such software library or work which has been
|
||||
distributed under these terms. A "work based on the Library" means either the
|
||||
Library or any derivative work under copyright law: that is to say, a work
|
||||
containing the Library or a portion of it, either verbatim or with modifications
|
||||
and/or translated straightforwardly into another language. (Hereinafter,
|
||||
translation is included without limitation in the term "modification".)
|
||||
|
||||
"Source code" for a work means the preferred form of the work for making
|
||||
modifications to it. For a library, complete source code means all the source
|
||||
code for all modules it contains, plus any associated interface definition
|
||||
files, plus the scripts used to control compilation and installation of the
|
||||
library.
|
||||
|
||||
Activities other than copying, distribution and modification are not covered by
|
||||
this License; they are outside its scope. The act of running a program using the
|
||||
Library is not restricted, and output from such a program is covered only if its
|
||||
contents constitute a work based on the Library (independent of the use of the
|
||||
Library in a tool for writing it). Whether that is true depends on what the
|
||||
Library does and what the program that uses the Library does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Library's complete source
|
||||
code as you receive it, in any medium, provided that you conspicuously and
|
||||
appropriately publish on each copy an appropriate copyright notice and
|
||||
disclaimer of warranty; keep intact all the notices that refer to this License
|
||||
and to the absence of any warranty; and distribute a copy of this License along
|
||||
with the Library.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and you may at
|
||||
your option offer warranty protection in exchange for a fee.
|
||||
|
||||
2. You may modify your copy or copies of the Library or any portion of it, thus
|
||||
forming a work based on the Library, and copy and distribute such modifications
|
||||
or work under the terms of Section 1 above, provided that you also meet all of
|
||||
these conditions:
|
||||
|
||||
a) The modified work must itself be a software library.
|
||||
b) You must cause the files modified to carry prominent notices stating that
|
||||
you changed the files and the date of any change.
|
||||
c) You must cause the whole of the work to be licensed at no charge to all
|
||||
third parties under the terms of this License.
|
||||
d) If a facility in the modified Library refers to a function or a table of
|
||||
data to be supplied by an application program that uses the facility, other than
|
||||
as an argument passed when the facility is invoked, then you must make a good
|
||||
faith effort to ensure that, in the event an application does not supply such
|
||||
function or table, the facility still operates, and performs whatever part of
|
||||
its purpose remains meaningful.
|
||||
|
||||
(For example, a function in a library to compute square roots has a purpose
|
||||
that is entirely well-defined independent of the application. Therefore,
|
||||
Subsection 2d requires that any application-supplied function or table used by
|
||||
this function must be optional: if the application does not supply it, the
|
||||
square root function must still compute square roots.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If identifiable
|
||||
sections of that work are not derived from the Library, and can be reasonably
|
||||
considered independent and separate works in themselves, then this License, and
|
||||
its terms, do not apply to those sections when you distribute them as separate
|
||||
works. But when you distribute the same sections as part of a whole which is a
|
||||
work based on the Library, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the entire whole,
|
||||
and thus to each and every part regardless of who wrote it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest your
|
||||
rights to work written entirely by you; rather, the intent is to exercise the
|
||||
right to control the distribution of derivative or collective works based on the
|
||||
Library.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Library with the
|
||||
Library (or with a work based on the Library) on a volume of a storage or
|
||||
distribution medium does not bring the other work under the scope of this
|
||||
License.
|
||||
|
||||
3. You may opt to apply the terms of the ordinary GNU General Public License
|
||||
instead of this License to a given copy of the Library. To do this, you must
|
||||
alter all the notices that refer to this License, so that they refer to the
|
||||
ordinary GNU General Public License, version 2, instead of to this License. (If
|
||||
a newer version than version 2 of the ordinary GNU General Public License has
|
||||
appeared, then you can specify that version instead if you wish.) Do not make
|
||||
any other change in these notices.
|
||||
|
||||
Once this change is made in a given copy, it is irreversible for that copy, so
|
||||
the ordinary GNU General Public License applies to all subsequent copies and
|
||||
derivative works made from that copy.
|
||||
|
||||
This option is useful when you wish to copy part of the code of the Library into
|
||||
a program that is not a library.
|
||||
|
||||
4. You may copy and distribute the Library (or a portion or derivative of it,
|
||||
under Section 2) in object code or executable form under the terms of Sections 1
|
||||
and 2 above provided that you accompany it with the complete corresponding
|
||||
machine-readable source code, which must be distributed under the terms of
|
||||
Sections 1 and 2 above on a medium customarily used for software interchange.
|
||||
|
||||
If distribution of object code is made by offering access to copy from a
|
||||
designated place, then offering equivalent access to copy the source code from
|
||||
the same place satisfies the requirement to distribute the source code, even
|
||||
though third parties are not compelled to copy the source along with the object
|
||||
code.
|
||||
|
||||
5. A program that contains no derivative of any portion of the Library, but is
|
||||
designed to work with the Library by being compiled or linked with it, is called
|
||||
a "work that uses the Library". Such a work, in isolation, is not a derivative
|
||||
work of the Library, and therefore falls outside the scope of this License.
|
||||
|
||||
However, linking a "work that uses the Library" with the Library creates an
|
||||
executable that is a derivative of the Library (because it contains portions of
|
||||
the Library), rather than a "work that uses the library". The executable is
|
||||
therefore covered by this License. Section 6 states terms for distribution of
|
||||
such executables.
|
||||
|
||||
When a "work that uses the Library" uses material from a header file that is
|
||||
part of the Library, the object code for the work may be a derivative work of
|
||||
the Library even though the source code is not. Whether this is true is
|
||||
especially significant if the work can be linked without the Library, or if the
|
||||
work is itself a library. The threshold for this to be true is not precisely
|
||||
defined by law.
|
||||
|
||||
If such an object file uses only numerical parameters, data structure layouts
|
||||
and accessors, and small macros and small inline functions (ten lines or less in
|
||||
length), then the use of the object file is unrestricted, regardless of whether
|
||||
it is legally a derivative work. (Executables containing this object code plus
|
||||
portions of the Library will still fall under Section 6.)
|
||||
|
||||
Otherwise, if the work is a derivative of the Library, you may distribute the
|
||||
object code for the work under the terms of Section 6. Any executables
|
||||
containing that work also fall under Section 6, whether or not they are linked
|
||||
directly with the Library itself.
|
||||
|
||||
6. As an exception to the Sections above, you may also compile or link a "work
|
||||
that uses the Library" with the Library to produce a work containing portions of
|
||||
the Library, and distribute that work under terms of your choice, provided that
|
||||
the terms permit modification of the work for the customer's own use and reverse
|
||||
engineering for debugging such modifications.
|
||||
|
||||
You must give prominent notice with each copy of the work that the Library is
|
||||
used in it and that the Library and its use are covered by this License. You
|
||||
must supply a copy of this License. If the work during execution displays
|
||||
copyright notices, you must include the copyright notice for the Library among
|
||||
them, as well as a reference directing the user to the copy of this License.
|
||||
Also, you must do one of these things:
|
||||
|
||||
a) Accompany the work with the complete corresponding machine-readable
|
||||
source code for the Library including whatever changes were used in the work
|
||||
(which must be distributed under Sections 1 and 2 above); and, if the work is an
|
||||
executable linked with the Library, with the complete machine-readable "work
|
||||
that uses the Library", as object code and/or source code, so that the user can
|
||||
modify the Library and then relink to produce a modified executable containing
|
||||
the modified Library. (It is understood that the user who changes the contents
|
||||
of definitions files in the Library will not necessarily be able to recompile
|
||||
the application to use the modified definitions.)
|
||||
b) Accompany the work with a written offer, valid for at least three years,
|
||||
to give the same user the materials specified in Subsection 6a, above, for a
|
||||
charge no more than the cost of performing this distribution.
|
||||
c) If distribution of the work is made by offering access to copy from a
|
||||
designated place, offer equivalent access to copy the above specified materials
|
||||
from the same place.
|
||||
d) Verify that the user has already received a copy of these materials or
|
||||
that you have already sent this user a copy.
|
||||
|
||||
For an executable, the required form of the "work that uses the Library" must
|
||||
include any data and utility programs needed for reproducing the executable from
|
||||
it. However, as a special exception, the source code distributed need not
|
||||
include anything that is normally distributed (in either source or binary form)
|
||||
with the major components (compiler, kernel, and so on) of the operating system
|
||||
on which the executable runs, unless that component itself accompanies the
|
||||
executable.
|
||||
|
||||
It may happen that this requirement contradicts the license restrictions of
|
||||
other proprietary libraries that do not normally accompany the operating system.
|
||||
Such a contradiction means you cannot use both them and the Library together in
|
||||
an executable that you distribute.
|
||||
|
||||
7. You may place library facilities that are a work based on the Library
|
||||
side-by-side in a single library together with other library facilities not
|
||||
covered by this License, and distribute such a combined library, provided that
|
||||
the separate distribution of the work based on the Library and of the other
|
||||
library facilities is otherwise permitted, and provided that you do these two
|
||||
things:
|
||||
|
||||
a) Accompany the combined library with a copy of the same work based on the
|
||||
Library, uncombined with any other library facilities. This must be distributed
|
||||
under the terms of the Sections above.
|
||||
b) Give prominent notice with the combined library of the fact that part of
|
||||
it is a work based on the Library, and explaining where to find the accompanying
|
||||
uncombined form of the same work.
|
||||
|
||||
8. You may not copy, modify, sublicense, link with, or distribute the Library
|
||||
except as expressly provided under this License. Any attempt otherwise to copy,
|
||||
modify, sublicense, link with, or distribute the Library is void, and will
|
||||
automatically terminate your rights under this License. However, parties who
|
||||
have received copies, or rights, from you under this License will not have their
|
||||
licenses terminated so long as such parties remain in full compliance.
|
||||
|
||||
9. You are not required to accept this License, since you have not signed it.
|
||||
However, nothing else grants you permission to modify or distribute the Library
|
||||
or its derivative works. These actions are prohibited by law if you do not
|
||||
accept this License. Therefore, by modifying or distributing the Library (or any
|
||||
work based on the Library), you indicate your acceptance of this License to do
|
||||
so, and all its terms and conditions for copying, distributing or modifying the
|
||||
Library or works based on it.
|
||||
|
||||
10. Each time you redistribute the Library (or any work based on the Library),
|
||||
the recipient automatically receives a license from the original licensor to
|
||||
copy, distribute, link with or modify the Library subject to these terms and
|
||||
conditions. You may not impose any further restrictions on the recipients'
|
||||
exercise of the rights granted herein. You are not responsible for enforcing
|
||||
compliance by third parties to this License.
|
||||
|
||||
11. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues), conditions
|
||||
are imposed on you (whether by court order, agreement or otherwise) that
|
||||
contradict the conditions of this License, they do not excuse you from the
|
||||
conditions of this License. If you cannot distribute so as to satisfy
|
||||
simultaneously your obligations under this License and any other pertinent
|
||||
obligations, then as a consequence you may not distribute the Library at all.
|
||||
For example, if a patent license would not permit royalty-free redistribution of
|
||||
the Library by all those who receive copies directly or indirectly through you,
|
||||
then the only way you could satisfy both it and this License would be to refrain
|
||||
entirely from distribution of the Library.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under any
|
||||
particular circumstance, the balance of the section is intended to apply, and
|
||||
the section as a whole is intended to apply in other circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any patents or
|
||||
other property right claims or to contest validity of any such claims; this
|
||||
section has the sole purpose of protecting the integrity of the free software
|
||||
distribution system which is implemented by public license practices. Many
|
||||
people have made generous contributions to the wide range of software
|
||||
distributed through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing to
|
||||
distribute software through any other system and a licensee cannot impose that
|
||||
choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to be a
|
||||
consequence of the rest of this License.
|
||||
|
||||
12. If the distribution and/or use of the Library is restricted in certain
|
||||
countries either by patents or by copyrighted interfaces, the original copyright
|
||||
holder who places the Library under this License may add an explicit
|
||||
geographical distribution limitation excluding those countries, so that
|
||||
distribution is permitted only in or among countries not thus excluded. In such
|
||||
case, this License incorporates the limitation as if written in the body of this
|
||||
License.
|
||||
|
||||
13. The Free Software Foundation may publish revised and/or new versions of the
|
||||
Library General Public License from time to time. Such new versions will be
|
||||
similar in spirit to the present version, but may differ in detail to address
|
||||
new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Library specifies
|
||||
a version number of this License which applies to it and "any later version",
|
||||
you have the option of following the terms and conditions either of that version
|
||||
or of any later version published by the Free Software Foundation. If the
|
||||
Library does not specify a license version number, you may choose any version
|
||||
ever published by the Free Software Foundation.
|
||||
|
||||
14. If you wish to incorporate parts of the Library into other free programs
|
||||
whose distribution conditions are incompatible with these, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free Software
|
||||
Foundation, write to the Free Software Foundation; we sometimes make exceptions
|
||||
for this. Our decision will be guided by the two goals of preserving the free
|
||||
status of all derivatives of our free software and of promoting the sharing and
|
||||
reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE
|
||||
LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED
|
||||
IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY "AS
|
||||
IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT
|
||||
NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
||||
PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
|
||||
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF
|
||||
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL
|
||||
ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE
|
||||
LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL,
|
||||
SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY
|
||||
TO USE THE LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
|
||||
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF
|
||||
THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER
|
||||
PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
|
||||
404
gstegl_src/gst-egl/gst-libs/gst/egl/egl.c
Normal file
404
gstegl_src/gst-egl/gst-libs/gst/egl/egl.c
Normal file
@@ -0,0 +1,404 @@
|
||||
/*
|
||||
* GStreamer EGL Library
|
||||
* Copyright (C) 2012 Collabora Ltd.
|
||||
* @author: Sebastian Dröge <sebastian.droege@collabora.co.uk>
|
||||
* *
|
||||
* 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;
|
||||
* version 2 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
|
||||
* 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
|
||||
|
||||
|
||||
#if defined (USE_EGL_RPI) && defined(__GNUC__)
|
||||
#ifndef __VCCOREVER__
|
||||
#define __VCCOREVER__ 0x04000000
|
||||
#endif
|
||||
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wredundant-decls"
|
||||
#pragma GCC optimize ("gnu89-inline")
|
||||
#endif
|
||||
|
||||
#define EGL_EGLEXT_PROTOTYPES
|
||||
|
||||
#include <gst/egl/egl.h>
|
||||
#include <string.h>
|
||||
|
||||
#if defined (USE_EGL_RPI) && defined(__GNUC__)
|
||||
#pragma GCC reset_options
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
struct _GstEGLDisplay
|
||||
{
|
||||
EGLDisplay display;
|
||||
volatile gint refcount;
|
||||
GDestroyNotify destroy_notify;
|
||||
|
||||
PFNEGLCREATEIMAGEKHRPROC eglCreateImage;
|
||||
PFNEGLDESTROYIMAGEKHRPROC eglDestroyImage;
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
GstMemory parent;
|
||||
|
||||
GstEGLDisplay *display;
|
||||
EGLImageKHR image;
|
||||
GstVideoGLTextureType type;
|
||||
GstVideoGLTextureOrientation orientation;
|
||||
|
||||
gpointer user_data;
|
||||
GDestroyNotify user_data_destroy;
|
||||
} GstEGLImageMemory;
|
||||
|
||||
#define GST_EGL_IMAGE_MEMORY(mem) ((GstEGLImageMemory*)(mem))
|
||||
|
||||
gboolean
|
||||
gst_egl_image_memory_is_mappable (void)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gst_is_egl_image_memory (GstMemory * mem)
|
||||
{
|
||||
g_return_val_if_fail (mem != NULL, FALSE);
|
||||
g_return_val_if_fail (mem->allocator != NULL, FALSE);
|
||||
|
||||
return g_strcmp0 (mem->allocator->mem_type, GST_EGL_IMAGE_MEMORY_TYPE) == 0;
|
||||
}
|
||||
|
||||
EGLImageKHR
|
||||
gst_egl_image_memory_get_image (GstMemory * mem)
|
||||
{
|
||||
g_return_val_if_fail (gst_is_egl_image_memory (mem), EGL_NO_IMAGE_KHR);
|
||||
|
||||
if (mem->parent)
|
||||
mem = mem->parent;
|
||||
|
||||
return GST_EGL_IMAGE_MEMORY (mem)->image;
|
||||
}
|
||||
|
||||
GstEGLDisplay *
|
||||
gst_egl_image_memory_get_display (GstMemory * mem)
|
||||
{
|
||||
g_return_val_if_fail (gst_is_egl_image_memory (mem), NULL);
|
||||
|
||||
if (mem->parent)
|
||||
mem = mem->parent;
|
||||
|
||||
return gst_egl_display_ref (GST_EGL_IMAGE_MEMORY (mem)->display);
|
||||
}
|
||||
|
||||
GstVideoGLTextureType
|
||||
gst_egl_image_memory_get_type (GstMemory * mem)
|
||||
{
|
||||
g_return_val_if_fail (gst_is_egl_image_memory (mem), -1);
|
||||
|
||||
if (mem->parent)
|
||||
mem = mem->parent;
|
||||
|
||||
return GST_EGL_IMAGE_MEMORY (mem)->type;
|
||||
}
|
||||
|
||||
GstVideoGLTextureOrientation
|
||||
gst_egl_image_memory_get_orientation (GstMemory * mem)
|
||||
{
|
||||
g_return_val_if_fail (gst_is_egl_image_memory (mem),
|
||||
GST_VIDEO_GL_TEXTURE_ORIENTATION_X_NORMAL_Y_NORMAL);
|
||||
|
||||
if (mem->parent)
|
||||
mem = mem->parent;
|
||||
|
||||
return GST_EGL_IMAGE_MEMORY (mem)->orientation;
|
||||
}
|
||||
|
||||
void
|
||||
gst_egl_image_memory_set_orientation (GstMemory * mem,
|
||||
GstVideoGLTextureOrientation orientation)
|
||||
{
|
||||
g_return_if_fail (gst_is_egl_image_memory (mem));
|
||||
|
||||
if (mem->parent)
|
||||
mem = mem->parent;
|
||||
|
||||
GST_EGL_IMAGE_MEMORY (mem)->orientation = orientation;
|
||||
}
|
||||
|
||||
static GstMemory *
|
||||
gst_egl_image_allocator_alloc_vfunc (GstAllocator * allocator, gsize size,
|
||||
GstAllocationParams * params)
|
||||
{
|
||||
g_warning
|
||||
("Use gst_egl_image_allocator_alloc() to allocate from this allocator");
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_egl_image_allocator_free_vfunc (GstAllocator * allocator, GstMemory * mem)
|
||||
{
|
||||
GstEGLImageMemory *emem = (GstEGLImageMemory *) mem;
|
||||
EGLDisplay display;
|
||||
|
||||
g_return_if_fail (gst_is_egl_image_memory (mem));
|
||||
|
||||
/* Shared memory should not destroy all the data */
|
||||
if (!mem->parent) {
|
||||
display = gst_egl_display_get (emem->display);
|
||||
if (emem->display->eglDestroyImage)
|
||||
emem->display->eglDestroyImage (display, emem->image);
|
||||
|
||||
if (emem->user_data_destroy)
|
||||
emem->user_data_destroy (emem->user_data);
|
||||
|
||||
gst_egl_display_unref (emem->display);
|
||||
}
|
||||
|
||||
g_slice_free (GstEGLImageMemory, emem);
|
||||
}
|
||||
|
||||
static gpointer
|
||||
gst_egl_image_mem_map (GstMemory * mem, gsize maxsize, GstMapFlags flags)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_egl_image_mem_unmap (GstMemory * mem)
|
||||
{
|
||||
}
|
||||
|
||||
static GstMemory *
|
||||
gst_egl_image_mem_share (GstMemory * mem, gssize offset, gssize size)
|
||||
{
|
||||
GstMemory *sub;
|
||||
GstMemory *parent;
|
||||
|
||||
if (offset != 0)
|
||||
return NULL;
|
||||
|
||||
if (size != -1 && size != (gssize)mem->size)
|
||||
return NULL;
|
||||
|
||||
/* find the real parent */
|
||||
if ((parent = mem->parent) == NULL)
|
||||
parent = (GstMemory *) mem;
|
||||
|
||||
if (size == -1)
|
||||
size = mem->size - offset;
|
||||
|
||||
sub = (GstMemory *) g_slice_new (GstEGLImageMemory);
|
||||
|
||||
/* the shared memory is always readonly */
|
||||
gst_memory_init (GST_MEMORY_CAST (sub), GST_MINI_OBJECT_FLAGS (parent) |
|
||||
GST_MINI_OBJECT_FLAG_LOCK_READONLY, mem->allocator, parent,
|
||||
mem->maxsize, mem->align, mem->offset + offset, size);
|
||||
|
||||
return sub;
|
||||
}
|
||||
|
||||
static GstMemory *
|
||||
gst_egl_image_mem_copy (GstMemory * mem, gssize offset, gssize size)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_egl_image_mem_is_span (GstMemory * mem1, GstMemory * mem2, gsize * offset)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
typedef GstAllocator GstEGLImageAllocator;
|
||||
typedef GstAllocatorClass GstEGLImageAllocatorClass;
|
||||
|
||||
GType gst_egl_image_allocator_get_type (void);
|
||||
G_DEFINE_TYPE (GstEGLImageAllocator, gst_egl_image_allocator,
|
||||
GST_TYPE_ALLOCATOR);
|
||||
|
||||
#define GST_TYPE_EGL_IMAGE_ALLOCATOR (gst_egl_image_mem_allocator_get_type())
|
||||
#define GST_IS_EGL_IMAGE_ALLOCATOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_EGL_IMAGE_ALLOCATOR))
|
||||
|
||||
static void
|
||||
gst_egl_image_allocator_class_init (GstEGLImageAllocatorClass * klass)
|
||||
{
|
||||
GstAllocatorClass *allocator_class = (GstAllocatorClass *) klass;
|
||||
|
||||
allocator_class->alloc = gst_egl_image_allocator_alloc_vfunc;
|
||||
allocator_class->free = gst_egl_image_allocator_free_vfunc;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_egl_image_allocator_init (GstEGLImageAllocator * allocator)
|
||||
{
|
||||
GstAllocator *alloc = GST_ALLOCATOR_CAST (allocator);
|
||||
|
||||
alloc->mem_type = GST_EGL_IMAGE_MEMORY_TYPE;
|
||||
alloc->mem_map = gst_egl_image_mem_map;
|
||||
alloc->mem_unmap = gst_egl_image_mem_unmap;
|
||||
alloc->mem_share = gst_egl_image_mem_share;
|
||||
alloc->mem_copy = gst_egl_image_mem_copy;
|
||||
alloc->mem_is_span = gst_egl_image_mem_is_span;
|
||||
|
||||
GST_OBJECT_FLAG_SET (allocator, GST_ALLOCATOR_FLAG_CUSTOM_ALLOC);
|
||||
}
|
||||
|
||||
static gpointer
|
||||
gst_egl_image_allocator_init_instance (gpointer data)
|
||||
{
|
||||
return g_object_new (gst_egl_image_allocator_get_type (), NULL);
|
||||
}
|
||||
|
||||
GstAllocator *
|
||||
gst_egl_image_allocator_obtain (void)
|
||||
{
|
||||
GstAllocator *allocator;
|
||||
|
||||
allocator = gst_egl_image_allocator_init_instance(NULL);
|
||||
return GST_ALLOCATOR (g_object_ref (allocator));
|
||||
}
|
||||
|
||||
GstMemory *
|
||||
gst_egl_image_allocator_alloc (GstAllocator * allocator,
|
||||
GstEGLDisplay * display, GstVideoGLTextureType type, gint width,
|
||||
gint height, gsize * size)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
GstMemory *
|
||||
gst_egl_image_allocator_wrap (GstAllocator * allocator,
|
||||
GstEGLDisplay * display, EGLImageKHR image, GstVideoGLTextureType type,
|
||||
GstMemoryFlags flags, gsize size, gpointer user_data,
|
||||
GDestroyNotify user_data_destroy)
|
||||
{
|
||||
GstEGLImageMemory *mem;
|
||||
|
||||
g_return_val_if_fail (display != NULL, NULL);
|
||||
g_return_val_if_fail (image != EGL_NO_IMAGE_KHR, NULL);
|
||||
|
||||
if (!allocator) {
|
||||
allocator = gst_egl_image_allocator_obtain ();
|
||||
}
|
||||
|
||||
mem = g_slice_new (GstEGLImageMemory);
|
||||
gst_memory_init (GST_MEMORY_CAST (mem), flags,
|
||||
allocator, NULL, size, 0, 0, size);
|
||||
|
||||
mem->display = gst_egl_display_ref (display);
|
||||
mem->image = image;
|
||||
mem->type = type;
|
||||
mem->orientation = GST_VIDEO_GL_TEXTURE_ORIENTATION_X_NORMAL_Y_NORMAL;
|
||||
|
||||
mem->user_data = user_data;
|
||||
mem->user_data_destroy = user_data_destroy;
|
||||
|
||||
return GST_MEMORY_CAST (mem);
|
||||
}
|
||||
|
||||
GstContext *
|
||||
gst_context_new_egl_display (GstEGLDisplay * display, gboolean persistent)
|
||||
{
|
||||
GstContext *context;
|
||||
GstStructure *s;
|
||||
|
||||
context = gst_context_new (GST_EGL_DISPLAY_CONTEXT_TYPE, persistent);
|
||||
s = gst_context_writable_structure (context);
|
||||
gst_structure_set (s, "display", GST_TYPE_EGL_DISPLAY, display, NULL);
|
||||
|
||||
return context;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gst_context_get_egl_display (GstContext * context, GstEGLDisplay ** display)
|
||||
{
|
||||
const GstStructure *s;
|
||||
|
||||
g_return_val_if_fail (GST_IS_CONTEXT (context), FALSE);
|
||||
g_return_val_if_fail (strcmp (gst_context_get_context_type (context),
|
||||
GST_EGL_DISPLAY_CONTEXT_TYPE) == 0, FALSE);
|
||||
|
||||
s = gst_context_get_structure (context);
|
||||
return gst_structure_get (s, "display", GST_TYPE_EGL_DISPLAY, display, NULL);
|
||||
}
|
||||
|
||||
GstEGLDisplay *
|
||||
gst_egl_display_new (EGLDisplay display, GDestroyNotify destroy_notify)
|
||||
{
|
||||
GstEGLDisplay *gdisplay;
|
||||
|
||||
gdisplay = g_slice_new (GstEGLDisplay);
|
||||
gdisplay->display = display;
|
||||
gdisplay->refcount = 1;
|
||||
gdisplay->destroy_notify = destroy_notify;
|
||||
|
||||
gdisplay->eglCreateImage =
|
||||
(PFNEGLCREATEIMAGEKHRPROC) eglGetProcAddress ("eglCreateImageKHR");
|
||||
gdisplay->eglDestroyImage =
|
||||
(PFNEGLDESTROYIMAGEKHRPROC) eglGetProcAddress ("eglDestroyImageKHR");
|
||||
|
||||
return gdisplay;
|
||||
}
|
||||
|
||||
GstEGLDisplay *
|
||||
gst_egl_display_ref (GstEGLDisplay * display)
|
||||
{
|
||||
g_return_val_if_fail (display != NULL, NULL);
|
||||
|
||||
g_atomic_int_inc (&display->refcount);
|
||||
|
||||
return display;
|
||||
}
|
||||
|
||||
void
|
||||
gst_egl_display_unref (GstEGLDisplay * display)
|
||||
{
|
||||
g_return_if_fail (display != NULL);
|
||||
|
||||
if (g_atomic_int_dec_and_test (&display->refcount)) {
|
||||
if (display->destroy_notify)
|
||||
display->destroy_notify (display->display);
|
||||
g_slice_free (GstEGLDisplay, display);
|
||||
}
|
||||
}
|
||||
|
||||
EGLDisplay
|
||||
gst_egl_display_get (GstEGLDisplay * display)
|
||||
{
|
||||
g_return_val_if_fail (display != NULL, EGL_NO_DISPLAY);
|
||||
|
||||
return display->display;
|
||||
}
|
||||
|
||||
EGLImageKHR
|
||||
gst_egl_display_image_create (GstEGLDisplay * display,
|
||||
EGLContext ctx,
|
||||
EGLenum target, EGLClientBuffer buffer, const EGLint * attrib_list)
|
||||
{
|
||||
if (!display->eglCreateImage)
|
||||
return EGL_NO_IMAGE_KHR;
|
||||
|
||||
return display->eglCreateImage (gst_egl_display_get (display), ctx, target,
|
||||
buffer, attrib_list);
|
||||
}
|
||||
|
||||
G_DEFINE_BOXED_TYPE (GstEGLDisplay, gst_egl_display,
|
||||
(GBoxedCopyFunc) gst_egl_display_ref,
|
||||
(GBoxedFreeFunc) gst_egl_display_unref);
|
||||
76
gstegl_src/gst-egl/gst-libs/gst/egl/egl.h
Normal file
76
gstegl_src/gst-egl/gst-libs/gst/egl/egl.h
Normal file
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
* GStreamer EGL Library
|
||||
* Copyright (C) 2012 Collabora Ltd.
|
||||
* @author: Sebastian Dröge <sebastian.droege@collabora.co.uk>
|
||||
* *
|
||||
* 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;
|
||||
* version 2 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
|
||||
* 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_EGL_H__
|
||||
#define __GST_EGL_H__
|
||||
|
||||
#include <gst/gst.h>
|
||||
#include <gst/video/video.h>
|
||||
#include <EGL/egl.h>
|
||||
#include <EGL/eglext.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GST_EGL_IMAGE_MEMORY_TYPE "EGLImage"
|
||||
|
||||
#define GST_CAPS_FEATURE_MEMORY_EGL_IMAGE "memory:EGLImage"
|
||||
|
||||
typedef struct _GstEGLDisplay GstEGLDisplay;
|
||||
|
||||
/* EGLImage GstMemory handling */
|
||||
gboolean gst_egl_image_memory_is_mappable (void);
|
||||
gboolean gst_is_egl_image_memory (GstMemory * mem);
|
||||
EGLImageKHR gst_egl_image_memory_get_image (GstMemory * mem);
|
||||
GstEGLDisplay *gst_egl_image_memory_get_display (GstMemory * mem);
|
||||
GstVideoGLTextureType gst_egl_image_memory_get_type (GstMemory * mem);
|
||||
GstVideoGLTextureOrientation gst_egl_image_memory_get_orientation (GstMemory * mem);
|
||||
void gst_egl_image_memory_set_orientation (GstMemory * mem,
|
||||
GstVideoGLTextureOrientation orientation);
|
||||
|
||||
/* Generic EGLImage allocator that doesn't support mapping, copying or anything */
|
||||
GstAllocator *gst_egl_image_allocator_obtain (void);
|
||||
GstMemory *gst_egl_image_allocator_alloc (GstAllocator * allocator,
|
||||
GstEGLDisplay * display, GstVideoGLTextureType type, gint width, gint height,
|
||||
gsize * size);
|
||||
GstMemory *gst_egl_image_allocator_wrap (GstAllocator * allocator,
|
||||
GstEGLDisplay * display, EGLImageKHR image, GstVideoGLTextureType type,
|
||||
GstMemoryFlags flags, gsize size, gpointer user_data,
|
||||
GDestroyNotify user_data_destroy);
|
||||
|
||||
#define GST_EGL_DISPLAY_CONTEXT_TYPE "gst.egl.EGLDisplay"
|
||||
GstContext * gst_context_new_egl_display (GstEGLDisplay * display, gboolean persistent);
|
||||
gboolean gst_context_get_egl_display (GstContext * context,
|
||||
GstEGLDisplay ** display);
|
||||
|
||||
/* EGLDisplay wrapper with refcount, connection is closed after last ref is gone */
|
||||
#define GST_TYPE_EGL_DISPLAY (gst_egl_display_get_type())
|
||||
GType gst_egl_display_get_type (void);
|
||||
|
||||
GstEGLDisplay *gst_egl_display_new (EGLDisplay display, GDestroyNotify destroy_notify);
|
||||
GstEGLDisplay *gst_egl_display_ref (GstEGLDisplay * display);
|
||||
void gst_egl_display_unref (GstEGLDisplay * display);
|
||||
EGLDisplay gst_egl_display_get (GstEGLDisplay * display);
|
||||
EGLImageKHR gst_egl_display_image_create (GstEGLDisplay * display,
|
||||
EGLContext ctx, EGLenum target, EGLClientBuffer buffer,
|
||||
const EGLint * attrib_list);
|
||||
|
||||
G_END_DECLS
|
||||
#endif /* __GST_EGL_H__ */
|
||||
663
gstegl_src/gst-egl/pre-gen-source_64/config.h
Normal file
663
gstegl_src/gst-egl/pre-gen-source_64/config.h
Normal file
@@ -0,0 +1,663 @@
|
||||
/* config.h. Generated from config.h.in by configure.
|
||||
* config.h.in. Generated from configure.ac by autoheader.
|
||||
*
|
||||
* Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
|
||||
* Copyright (c) 2022, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License, version 2.1, as published by the Free Software Foundation.
|
||||
*
|
||||
* 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 program. If not, see
|
||||
* <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/* Define if building universal (internal helper macro) */
|
||||
/* #undef AC_APPLE_UNIVERSAL_BUILD */
|
||||
|
||||
/* Default audio sink */
|
||||
#define DEFAULT_AUDIOSINK "autoaudiosink"
|
||||
|
||||
/* Default audio source */
|
||||
#define DEFAULT_AUDIOSRC "alsasrc"
|
||||
|
||||
/* Default video sink */
|
||||
#define DEFAULT_VIDEOSINK "autovideosink"
|
||||
|
||||
/* Default video source */
|
||||
#define DEFAULT_VIDEOSRC "v4l2src"
|
||||
|
||||
/* Default visualizer */
|
||||
#define DEFAULT_VISUALIZER "goom"
|
||||
|
||||
/* Disable Orc */
|
||||
#define DISABLE_ORC 1
|
||||
|
||||
/* Define if an old libdts is used */
|
||||
/* #undef DTS_OLD */
|
||||
|
||||
/* Define to 1 if translation of program messages to the user's native
|
||||
language is requested. */
|
||||
#define ENABLE_NLS 1
|
||||
|
||||
/* The x in 2.x */
|
||||
/* #undef FAAD2_MINOR_VERSION */
|
||||
|
||||
/* Define if AAC is using new api prefix */
|
||||
/* #undef FAAD_IS_NEAAC */
|
||||
|
||||
/* gettext package name */
|
||||
#define GETTEXT_PACKAGE "gst-plugins-bad-1.0"
|
||||
|
||||
/* The GIO library directory. */
|
||||
#define GIO_LIBDIR "/usr/lib/aarch64-linux-gnu"
|
||||
|
||||
/* The GIO modules directory. */
|
||||
#define GIO_MODULE_DIR "/usr/lib/aarch64-linux-gnu/gio/modules"
|
||||
|
||||
/* Define if GSM header in gsm/ subdir */
|
||||
/* #undef GSM_HEADER_IN_SUBDIR */
|
||||
|
||||
/* GStreamer API Version */
|
||||
#define GST_API_VERSION "1.0"
|
||||
|
||||
/* Extra platform specific plugin suffix */
|
||||
/* #undef GST_EXTRA_MODULE_SUFFIX */
|
||||
|
||||
/* Defined if gcov is enabled to force a rebuild due to config.h changing */
|
||||
/* #undef GST_GCOV_ENABLED */
|
||||
|
||||
/* Defined when registry scanning through fork is unsafe */
|
||||
/* #undef GST_HAVE_UNSAFE_FORK */
|
||||
|
||||
/* Default errorlevel to use */
|
||||
#define GST_LEVEL_DEFAULT GST_LEVEL_NONE
|
||||
|
||||
/* GStreamer license */
|
||||
#define GST_LICENSE "LGPL"
|
||||
|
||||
/* mjpegtools API evolution */
|
||||
#define GST_MJPEGTOOLS_API 0
|
||||
|
||||
/* package name in plugins */
|
||||
#define GST_PACKAGE_NAME "GStreamer Nvidia Bad Plug-ins source release"
|
||||
|
||||
/* package origin */
|
||||
#define GST_PACKAGE_ORIGIN "Unknown package origin"
|
||||
|
||||
/* GStreamer package release date/time for plugins as YYYY-MM-DD */
|
||||
#define GST_PACKAGE_RELEASE_DATETIME "2014-02-08"
|
||||
|
||||
/* Define if static plugins should be built */
|
||||
/* #undef GST_PLUGIN_BUILD_STATIC */
|
||||
|
||||
/* Define to enable Windows ACM library (used by acm). */
|
||||
/* #undef HAVE_ACM */
|
||||
|
||||
/* Define to enable Android Media (used by androidmedia). */
|
||||
/* #undef HAVE_ANDROID_MEDIA */
|
||||
|
||||
/* Define to enable AirPort Express Wireless sink (used by apexsink). */
|
||||
/* #undef HAVE_APEXSINK */
|
||||
|
||||
/* Define to enable Apple video (used by applemedia). */
|
||||
/* #undef HAVE_APPLE_MEDIA */
|
||||
|
||||
/* Define to enable ASS/SSA renderer (used by assrender). */
|
||||
/* #undef HAVE_ASSRENDER */
|
||||
|
||||
/* Define to enable AVC Video Services (used by avcsrc). */
|
||||
/* #undef HAVE_AVC */
|
||||
|
||||
/* Define to enable Bluez (used by bluez). */
|
||||
/* #undef HAVE_BLUEZ */
|
||||
|
||||
/* Define to enable bz2 library (used by bz2). */
|
||||
/* #undef HAVE_BZ2 */
|
||||
|
||||
/* Define to enable cdaudio (used by cdaudio). */
|
||||
/* #undef HAVE_CDAUDIO */
|
||||
|
||||
/* Define to 1 if you have the MacOS X function CFLocaleCopyCurrent in the
|
||||
CoreFoundation framework. */
|
||||
/* #undef HAVE_CFLOCALECOPYCURRENT */
|
||||
|
||||
/* Define to 1 if you have the MacOS X function CFPreferencesCopyAppValue in
|
||||
the CoreFoundation framework. */
|
||||
/* #undef HAVE_CFPREFERENCESCOPYAPPVALUE */
|
||||
|
||||
/* Define to enable chromaprint (used by chromaprint). */
|
||||
/* #undef HAVE_CHROMAPRINT */
|
||||
|
||||
/* Define if the target CPU is an Alpha */
|
||||
/* #undef HAVE_CPU_ALPHA */
|
||||
|
||||
/* Define if the target CPU is an ARM */
|
||||
#define HAVE_CPU_ARM 1
|
||||
|
||||
/* Define if the target CPU is a CRIS */
|
||||
/* #undef HAVE_CPU_CRIS */
|
||||
|
||||
/* Define if the target CPU is a CRISv32 */
|
||||
/* #undef HAVE_CPU_CRISV32 */
|
||||
|
||||
/* Define if the target CPU is a HPPA */
|
||||
/* #undef HAVE_CPU_HPPA */
|
||||
|
||||
/* Define if the target CPU is an x86 */
|
||||
/* #undef HAVE_CPU_I386 */
|
||||
|
||||
/* Define if the target CPU is a IA64 */
|
||||
/* #undef HAVE_CPU_IA64 */
|
||||
|
||||
/* Define if the target CPU is a M68K */
|
||||
/* #undef HAVE_CPU_M68K */
|
||||
|
||||
/* Define if the target CPU is a MIPS */
|
||||
/* #undef HAVE_CPU_MIPS */
|
||||
|
||||
/* Define if the target CPU is a PowerPC */
|
||||
/* #undef HAVE_CPU_PPC */
|
||||
|
||||
/* Define if the target CPU is a 64 bit PowerPC */
|
||||
/* #undef HAVE_CPU_PPC64 */
|
||||
|
||||
/* Define if the target CPU is a S390 */
|
||||
/* #undef HAVE_CPU_S390 */
|
||||
|
||||
/* Define if the target CPU is a SPARC */
|
||||
/* #undef HAVE_CPU_SPARC */
|
||||
|
||||
/* Define if the target CPU is a x86_64 */
|
||||
/* #undef HAVE_CPU_X86_64 */
|
||||
|
||||
/* Define to enable Curl plugin (used by curl). */
|
||||
/* #undef HAVE_CURL */
|
||||
|
||||
/* Define to enable daala (used by daala). */
|
||||
/* #undef HAVE_DAALA */
|
||||
|
||||
/* Define to enable DASH plug-in (used by dash). */
|
||||
#define HAVE_DASH /**/
|
||||
|
||||
/* Define to enable libdc1394 (used by dc1394). */
|
||||
/* #undef HAVE_DC1394 */
|
||||
|
||||
/* Define if the GNU dcgettext() function is already present or preinstalled.
|
||||
*/
|
||||
#define HAVE_DCGETTEXT 1
|
||||
|
||||
/* Define to enable decklink (used by decklink). */
|
||||
#define HAVE_DECKLINK /**/
|
||||
|
||||
/* Define to enable Direct3D plug-in (used by direct3dsink). */
|
||||
/* #undef HAVE_DIRECT3D */
|
||||
|
||||
/* Define to enable DirectDraw plug-in (used by directdrawsink). */
|
||||
/* #undef HAVE_DIRECTDRAW */
|
||||
|
||||
/* Define to enable directfb (used by dfbvideosink ). */
|
||||
/* #undef HAVE_DIRECTFB */
|
||||
|
||||
/* Define to enable DirectShow plug-in (used by winks). */
|
||||
/* #undef HAVE_DIRECTSHOW */
|
||||
|
||||
/* Define to enable DirectSound (used by directsoundsrc). */
|
||||
/* #undef HAVE_DIRECTSOUND */
|
||||
|
||||
/* Define to 1 if you have the <dlfcn.h> header file. */
|
||||
#define HAVE_DLFCN_H 1
|
||||
|
||||
/* define for working do while(0) macros */
|
||||
#define HAVE_DOWHILE_MACROS 1
|
||||
|
||||
/* Define to enable dts library (used by dtsdec). */
|
||||
/* #undef HAVE_DTS */
|
||||
|
||||
/* Define to enable DVB Source (used by dvb). */
|
||||
#define HAVE_DVB /**/
|
||||
|
||||
/* Define to enable eglgles sink (used by eglgles). */
|
||||
#define HAVE_EGLGLES /**/
|
||||
|
||||
/* Define to enable building of experimental plug-ins. */
|
||||
/* #undef HAVE_EXPERIMENTAL */
|
||||
|
||||
/* Define to enable building of plug-ins with external deps. */
|
||||
#define HAVE_EXTERNAL /**/
|
||||
|
||||
/* Define to enable AAC encoder plug-in (used by faac). */
|
||||
/* #undef HAVE_FAAC */
|
||||
|
||||
/* Define to enable AAC decoder plug-in (used by faad). */
|
||||
/* #undef HAVE_FAAD */
|
||||
|
||||
/* Define to enable linux framebuffer (used by fbdevsink). */
|
||||
#define HAVE_FBDEV /**/
|
||||
|
||||
/* Define to 1 if you have the <fcntl.h> header file. */
|
||||
/* #undef HAVE_FCNTL_H */
|
||||
|
||||
/* FIONREAD ioctl found in sys/filio.h */
|
||||
/* #undef HAVE_FIONREAD_IN_SYS_FILIO */
|
||||
|
||||
/* FIONREAD ioctl found in sys/ioclt.h */
|
||||
#define HAVE_FIONREAD_IN_SYS_IOCTL 1
|
||||
|
||||
/* Define to enable Flite plugin (used by flite). */
|
||||
/* #undef HAVE_FLITE */
|
||||
|
||||
/* Define to enable fluidsynth (used by fluidsynth). */
|
||||
/* #undef HAVE_FLUIDSYNTH */
|
||||
|
||||
/* Define to 1 if you have the `getpagesize' function. */
|
||||
#define HAVE_GETPAGESIZE 1
|
||||
|
||||
/* Define if the GNU gettext() function is already present or preinstalled. */
|
||||
#define HAVE_GETTEXT 1
|
||||
|
||||
/* Define to enable gme decoder (used by gme). */
|
||||
/* #undef HAVE_GME */
|
||||
|
||||
/* Define to 1 if you have the `gmtime_r' function. */
|
||||
#define HAVE_GMTIME_R 1
|
||||
|
||||
/* Define to enable GSettings plugin (used by gsettings). */
|
||||
/* #undef HAVE_GSETTINGS */
|
||||
|
||||
/* Define to enable GSM library (used by gsmenc gsmdec). */
|
||||
/* #undef HAVE_GSM */
|
||||
|
||||
/* Define if gudev is installed */
|
||||
/* #undef HAVE_GUDEV */
|
||||
|
||||
/* Define to 1 if you have the <highgui.h> header file. */
|
||||
/* #undef HAVE_HIGHGUI_H */
|
||||
|
||||
/* Define to enable http live streaming plugin (used by hls). */
|
||||
/* #undef HAVE_HLS */
|
||||
|
||||
/* Define if you have the iconv() function and it works. */
|
||||
/* #undef HAVE_ICONV */
|
||||
|
||||
/* Define to 1 if you have the <inttypes.h> header file. */
|
||||
#define HAVE_INTTYPES_H 1
|
||||
|
||||
/* Define if building for Apple iOS */
|
||||
/* #undef HAVE_IOS */
|
||||
|
||||
/* Define to enable Kate (used by kate). */
|
||||
/* #undef HAVE_KATE */
|
||||
|
||||
/* Define to enable ladspa (used by ladspa). */
|
||||
/* #undef HAVE_LADSPA */
|
||||
|
||||
/* Define if gme 0.5.6 or newer is available */
|
||||
/* #undef HAVE_LIBGME_ACCURACY */
|
||||
|
||||
/* Define to enable mms protocol library (used by libmms). */
|
||||
/* #undef HAVE_LIBMMS */
|
||||
|
||||
/* Define to 1 if you have the `nsl' library (-lnsl). */
|
||||
/* #undef HAVE_LIBNSL */
|
||||
|
||||
/* Define to 1 if you have the `socket' library (-lsocket). */
|
||||
/* #undef HAVE_LIBSOCKET */
|
||||
|
||||
/* Define if libusb 1.x is installed */
|
||||
/* #undef HAVE_LIBUSB */
|
||||
|
||||
/* Define to enable Linear Systems SDI plugin (used by linsys). */
|
||||
/* #undef HAVE_LINSYS */
|
||||
|
||||
/* Define if we have liblrdf */
|
||||
/* #undef HAVE_LRDF */
|
||||
|
||||
/* Define to enable lv2 (used by lv2). */
|
||||
/* #undef HAVE_LV2 */
|
||||
|
||||
/* Define to 1 if you have the <memory.h> header file. */
|
||||
#define HAVE_MEMORY_H 1
|
||||
|
||||
/* Define to enable Multi Format Codec (used by mfc). */
|
||||
#define HAVE_MFC /**/
|
||||
|
||||
/* Define to enable libmimic library (used by mimic). */
|
||||
/* #undef HAVE_MIMIC */
|
||||
|
||||
/* Define to 1 if you have a working `mmap' system call. */
|
||||
#define HAVE_MMAP 1
|
||||
|
||||
/* Define to enable modplug (used by modplug). */
|
||||
/* #undef HAVE_MODPLUG */
|
||||
|
||||
/* Define to enable mpeg2enc (used by mpeg2enc). */
|
||||
/* #undef HAVE_MPEG2ENC */
|
||||
|
||||
/* Define to enable mpg123 audio decoder (used by mpg123). */
|
||||
/* #undef HAVE_MPG123 */
|
||||
|
||||
/* Define to enable mplex (used by mplex). */
|
||||
/* #undef HAVE_MPLEX */
|
||||
|
||||
/* Define to 1 if you have the <msacm.h> header file. */
|
||||
/* #undef HAVE_MSACM_H */
|
||||
|
||||
/* Define to enable musepackdec (used by musepack). */
|
||||
/* #undef HAVE_MUSEPACK */
|
||||
|
||||
/* Define to enable MythTV client plugins (used by mythtvsrc). */
|
||||
/* #undef HAVE_MYTHTV */
|
||||
|
||||
/* Define to enable nas plug-in (used by nassink). */
|
||||
/* #undef HAVE_NAS */
|
||||
|
||||
/* Define to enable neon http client plugins (used by neonhttpsrc). */
|
||||
/* #undef HAVE_NEON */
|
||||
|
||||
/* Define to 1 if you have the <netinet/in.h> header file. */
|
||||
/* #undef HAVE_NETINET_IN_H */
|
||||
|
||||
/* Define to 1 if you have the <netinet/ip.h> header file. */
|
||||
/* #undef HAVE_NETINET_IP_H */
|
||||
|
||||
/* Define to 1 if you have the <netinet/tcp.h> header file. */
|
||||
/* #undef HAVE_NETINET_TCP_H */
|
||||
|
||||
/* Define to enable ofa plugins (used by ofa). */
|
||||
/* #undef HAVE_OFA */
|
||||
|
||||
/* Define to enable OpenAL plugin (used by openal). */
|
||||
/* #undef HAVE_OPENAL */
|
||||
|
||||
/* Define to enable opencv plugins (used by opencv). */
|
||||
/* #undef HAVE_OPENCV */
|
||||
|
||||
/* Define to 1 if you have the <opencv2/highgui/highgui_c.h> header file. */
|
||||
/* #undef HAVE_OPENCV2_HIGHGUI_HIGHGUI_C_H */
|
||||
|
||||
/* Define to enable openjpeg library (used by openjpeg). */
|
||||
/* #undef HAVE_OPENJPEG */
|
||||
|
||||
/* Define to enable OpenSL ES (used by opensl). */
|
||||
/* #undef HAVE_OPENSLES */
|
||||
|
||||
/* Define to enable opus (used by opus). */
|
||||
/* #undef HAVE_OPUS */
|
||||
|
||||
/* Use Orc */
|
||||
/* #undef HAVE_ORC */
|
||||
|
||||
/* Apple Mac OS X operating system detected */
|
||||
/* #undef HAVE_OSX */
|
||||
|
||||
/* Define to enable OSX video (used by osxvideosrc). */
|
||||
/* #undef HAVE_OSX_VIDEO */
|
||||
|
||||
/* Define to 1 if you have the <pthread.h> header file. */
|
||||
#define HAVE_PTHREAD_H 1
|
||||
|
||||
/* Define to enable pvrvideosink (used by pvr). */
|
||||
/* #undef HAVE_PVR */
|
||||
|
||||
/* Define to enable QuickTime wrapper (used by qtwrapper). */
|
||||
/* #undef HAVE_QUICKTIME */
|
||||
|
||||
/* Define if RDTSC is available */
|
||||
/* #undef HAVE_RDTSC */
|
||||
|
||||
/* Define to enable resindvd plugin (used by resindvd). */
|
||||
/* #undef HAVE_RESINDVD */
|
||||
|
||||
/* Define to enable rsvg decoder (used by rsvg). */
|
||||
/* #undef HAVE_RSVG */
|
||||
|
||||
/* Have RSVG 2.36.2 or newer */
|
||||
/* #undef HAVE_RSVG_2_36_2 */
|
||||
|
||||
/* Define to enable rtmp library (used by rtmp). */
|
||||
/* #undef HAVE_RTMP */
|
||||
|
||||
/* Define to enable SBC bluetooth audio codec (used by sbc). */
|
||||
/* #undef HAVE_SBC */
|
||||
|
||||
/* Define to enable Schroedinger video codec (used by schro). */
|
||||
/* #undef HAVE_SCHRO */
|
||||
|
||||
/* Define to enable SDL plug-in (used by sdlvideosink sdlaudiosink). */
|
||||
/* #undef HAVE_SDL */
|
||||
|
||||
/* Define to enable POSIX shared memory source and sink (used by shm). */
|
||||
#define HAVE_SHM /**/
|
||||
|
||||
/* Define to enable Smooth Streaming plug-in (used by smoothstreaming). */
|
||||
#define HAVE_SMOOTHSTREAMING /**/
|
||||
|
||||
/* Define to enable sndfile plug-in (used by sfsrc sfsink). */
|
||||
/* #undef HAVE_SNDFILE */
|
||||
|
||||
/* Define to enable sndio audio (used by sndio). */
|
||||
/* #undef HAVE_SNDIO */
|
||||
|
||||
/* Define to enable soundtouch plug-in (used by soundtouch). */
|
||||
/* #undef HAVE_SOUNDTOUCH */
|
||||
|
||||
/* Defined if the available libSoundTouch is >= 1.4 */
|
||||
/* #undef HAVE_SOUNDTOUCH_1_4 */
|
||||
|
||||
/* Define to enable Spandsp (used by spandsp). */
|
||||
/* #undef HAVE_SPANDSP */
|
||||
|
||||
/* Define to enable spc decoder (used by spc). */
|
||||
/* #undef HAVE_SPC */
|
||||
|
||||
/* Define to enable srtp library (used by srtp). */
|
||||
/* #undef HAVE_SRTP */
|
||||
|
||||
/* Define to 1 if you have the <stdint.h> header file. */
|
||||
#define HAVE_STDINT_H 1
|
||||
|
||||
/* Define to 1 if you have the <stdlib.h> header file. */
|
||||
#define HAVE_STDLIB_H 1
|
||||
|
||||
/* Define to 1 if you have the <strings.h> header file. */
|
||||
#define HAVE_STRINGS_H 1
|
||||
|
||||
/* Define to 1 if you have the <string.h> header file. */
|
||||
#define HAVE_STRING_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/param.h> header file. */
|
||||
#define HAVE_SYS_PARAM_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/socket.h> header file. */
|
||||
#define HAVE_SYS_SOCKET_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/stat.h> header file. */
|
||||
#define HAVE_SYS_STAT_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/time.h> header file. */
|
||||
#define HAVE_SYS_TIME_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/types.h> header file. */
|
||||
#define HAVE_SYS_TYPES_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/utsname.h> header file. */
|
||||
#define HAVE_SYS_UTSNAME_H 1
|
||||
|
||||
/* Define to enable Teletext decoder (used by teletextdec). */
|
||||
/* #undef HAVE_TELETEXTDEC */
|
||||
|
||||
/* Define if libtiger is available */
|
||||
/* #undef HAVE_TIGER */
|
||||
|
||||
/* Define to enable timidity midi soft synth plugin (used by timidity). */
|
||||
/* #undef HAVE_TIMIDITY */
|
||||
|
||||
/* Define to 1 if you have the <unistd.h> header file. */
|
||||
#define HAVE_UNISTD_H 1
|
||||
|
||||
/* Define to enable UVC H264 (used by uvch264). */
|
||||
/* #undef HAVE_UVCH264 */
|
||||
|
||||
/* Define if valgrind should be used */
|
||||
/* #undef HAVE_VALGRIND */
|
||||
|
||||
/* Define to enable Video CD (used by vcdsrc). */
|
||||
/* #undef HAVE_VCD */
|
||||
|
||||
/* Define to enable VDPAU (used by vdpau). */
|
||||
/* #undef HAVE_VDPAU */
|
||||
|
||||
/* Define to enable vo-aacenc library (used by vo-aacenc). */
|
||||
/* #undef HAVE_VOAACENC */
|
||||
|
||||
/* Define to enable vo-amrwbenc library (used by vo-amrwbenc). */
|
||||
/* #undef HAVE_VOAMRWBENC */
|
||||
|
||||
/* Define to enable WASAPI plug-in (used by wasapi). */
|
||||
/* #undef HAVE_WASAPI */
|
||||
|
||||
/* Define to enable wayland sink (used by wayland ). */
|
||||
#define HAVE_WAYLAND /**/
|
||||
|
||||
/* Define to enable WebP (used by webp ). */
|
||||
/* #undef HAVE_WEBP */
|
||||
|
||||
/* Define to enable wildmidi midi soft synth plugin (used by wildmidi). */
|
||||
/* #undef HAVE_WILDMIDI */
|
||||
|
||||
/* Have WildMidi 0.2.2 or earlier library */
|
||||
/* #undef HAVE_WILDMIDI_0_2_2 */
|
||||
|
||||
/* Defined if compiling for Windows */
|
||||
/* #undef HAVE_WIN32 */
|
||||
|
||||
/* Define to 1 if you have the <windows.h> header file. */
|
||||
/* #undef HAVE_WINDOWS_H */
|
||||
|
||||
/* Define to enable Windows internet library (used by wininet). */
|
||||
/* #undef HAVE_WININET */
|
||||
|
||||
/* Define to 1 if you have the <wininet.h> header file. */
|
||||
/* #undef HAVE_WININET_H */
|
||||
|
||||
/* Define to enable winscreencap plug-in (used by winscreencap). */
|
||||
/* #undef HAVE_WINSCREENCAP */
|
||||
|
||||
/* Define to 1 if you have the <winsock2.h> header file. */
|
||||
/* #undef HAVE_WINSOCK2_H */
|
||||
|
||||
/* Define to 1 if you have the <ws2tcpip.h> header file. */
|
||||
/* #undef HAVE_WS2TCPIP_H */
|
||||
|
||||
/* Define if you have X11 library */
|
||||
#define HAVE_X11 1
|
||||
|
||||
/* Define to enable xvid plugins (used by xvid). */
|
||||
/* #undef HAVE_XVID */
|
||||
|
||||
/* Define to enable ZBar barcode detector (used by zbar). */
|
||||
/* #undef HAVE_ZBAR */
|
||||
|
||||
/* the host CPU */
|
||||
#define HOST_CPU "aarch64"
|
||||
|
||||
/* library dir */
|
||||
#define LIBDIR "/usr/lib"
|
||||
|
||||
/* gettext locale dir */
|
||||
#define LOCALEDIR "/usr/share/locale"
|
||||
|
||||
/* Define to the sub-directory in which libtool stores uninstalled libraries.
|
||||
*/
|
||||
#define LT_OBJDIR ".libs/"
|
||||
|
||||
/* Define if the old MusePack API is used */
|
||||
/* #undef MPC_IS_OLD_API */
|
||||
|
||||
/* opencv install prefix */
|
||||
#define OPENCV_PREFIX ""
|
||||
|
||||
/* Name of package */
|
||||
#define PACKAGE "gst-plugins-bad"
|
||||
|
||||
/* Define to the address where bug reports for this package should be sent. */
|
||||
#define PACKAGE_BUGREPORT "http://bugzilla.gnome.org/enter_bug.cgi?product=GStreamer"
|
||||
|
||||
/* Define to the full name of this package. */
|
||||
#define PACKAGE_NAME "GStreamer Bad Plug-ins"
|
||||
|
||||
/* Define to the full name and version of this package. */
|
||||
#define PACKAGE_STRING "GStreamer Bad Plug-ins 1.2.3"
|
||||
|
||||
/* Define to the one symbol short name of this package. */
|
||||
#define PACKAGE_TARNAME "gst-plugins-bad"
|
||||
|
||||
/* Define to the home page for this package. */
|
||||
#define PACKAGE_URL ""
|
||||
|
||||
/* Define to the version of this package. */
|
||||
#define PACKAGE_VERSION "1.2.3"
|
||||
|
||||
/* directory where plugins are located */
|
||||
#define PLUGINDIR "/usr/lib/gstreamer-1.0"
|
||||
|
||||
/* The size of `char', as computed by sizeof. */
|
||||
/* #undef SIZEOF_CHAR */
|
||||
|
||||
/* The size of `int', as computed by sizeof. */
|
||||
/* #undef SIZEOF_INT */
|
||||
|
||||
/* The size of `long', as computed by sizeof. */
|
||||
/* #undef SIZEOF_LONG */
|
||||
|
||||
/* The size of `short', as computed by sizeof. */
|
||||
/* #undef SIZEOF_SHORT */
|
||||
|
||||
/* The size of `void*', as computed by sizeof. */
|
||||
/* #undef SIZEOF_VOIDP */
|
||||
|
||||
/* Define to 1 if you have the ANSI C header files. */
|
||||
#define STDC_HEADERS 1
|
||||
|
||||
/* the target CPU */
|
||||
#define TARGET_CPU "aarch64"
|
||||
|
||||
/* Define location of timidity.cfg */
|
||||
/* #undef TIMIDITY_CFG */
|
||||
|
||||
/* Use Mali FB EGL window system */
|
||||
/* #undef USE_EGL_MALI_FB */
|
||||
|
||||
/* Use RPi EGL window system */
|
||||
/* #undef USE_EGL_RPI */
|
||||
|
||||
/* Use X11 EGL window system */
|
||||
#define USE_EGL_X11 1
|
||||
|
||||
/* Version number of package */
|
||||
#define VERSION "1.2.3"
|
||||
|
||||
/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
|
||||
significant byte first (like Motorola and SPARC, unlike Intel). */
|
||||
#if defined AC_APPLE_UNIVERSAL_BUILD
|
||||
# if defined __BIG_ENDIAN__
|
||||
# define WORDS_BIGENDIAN 1
|
||||
# endif
|
||||
#else
|
||||
# ifndef WORDS_BIGENDIAN
|
||||
/* # undef WORDS_BIGENDIAN */
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* Define to 1 if the X Window System is missing or not being used. */
|
||||
/* #undef X_DISPLAY_MISSING */
|
||||
|
||||
/* We need at least WinXP SP2 for __stat64 */
|
||||
/* #undef __MSVCRT_VERSION__ */
|
||||
1
push_info.txt
Normal file
1
push_info.txt
Normal file
@@ -0,0 +1 @@
|
||||
jetson_35.4.1
|
||||
Reference in New Issue
Block a user