mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-26 11:41:09 +00:00
nvdec,nvenc: Port to dynamic library loading
... and put them into new nvcodec plugin. * nvcodec plugin Now each nvenc and nvdec element is moved to be a part of nvcodec plugin for better interoperability. Additionally, cuda runtime API header dependencies (i.e., cuda_runtime_api.h and cuda_gl_interop.h) are removed. Note that cuda runtime APIs have prefix "cuda". Since 1.16 release with Windows support, only "cuda.h" and "cudaGL.h" dependent symbols have been used except for some defined types. However, those types could be replaced with other types which were defined by "cuda.h". * dynamic library loading CUDA library will be opened with g_module_open() instead of build-time linking. On Windows, nvcuda.dll is installed to system path by CUDA Toolkit installer, and on *nix, user should ensure that libcuda.so.1 can be loadable (i.e., via LD_LIBRARY_PATH or default dlopen path) Therefore, NVIDIA_VIDEO_CODEC_SDK_PATH env build time dependency for Windows is removed.
This commit is contained in:
parent
5c3879ace6
commit
c18fda03d9
32 changed files with 1057 additions and 509 deletions
104
configure.ac
104
configure.ac
|
@ -881,103 +881,60 @@ AG_GST_CHECK_FEATURE(CUDA, [NVIDIA CUDA API],, [
|
|||
HAVE_CUDA="yes"
|
||||
if test "x$CUDA_PREFIX" != "x"; then
|
||||
dnl only override if not already set
|
||||
if test "x$CUDA_CFLAGS" = "x" -a "x$CUDA_LIBS" = "x"; then
|
||||
if test "x$CUDA_CFLAGS" = "x"; then
|
||||
dnl this is an educated guess, user can always override these
|
||||
CUDA_CFLAGS="-I$CUDA_PREFIX/include"
|
||||
CUDA_LIBS="-L$CUDA_PREFIX/lib -L$CUDA_PREFIX/lib64 -L$CUDA_PREFIX/lib/stubs -L$CUDA_PREFIX/lib64/stubs -lcuda -lcudart"
|
||||
fi
|
||||
else
|
||||
PKG_CHECK_MODULES([CUDA], [cuda-10.1 cudart-10.1],, [
|
||||
PKG_CHECK_MODULES([CUDA], [cuda-10.0 cudart-10.0],, [
|
||||
PKG_CHECK_MODULES([CUDA], [cuda-9.2 cudart-9.2],, [
|
||||
PKG_CHECK_MODULES([CUDA], [cuda-9.1 cudart-9.1],, [
|
||||
PKG_CHECK_MODULES([CUDA], [cuda-9.0 cudart-9.0],, [
|
||||
PKG_CHECK_MODULES([CUDA], [cuda-8.0 cudart-8.0],, [
|
||||
PKG_CHECK_MODULES([CUDA], [cuda-7.5 cudart-7.5],, [
|
||||
PKG_CHECK_MODULES([CUDA], [cuda-7.0 cudart-7.0],, [
|
||||
PKG_CHECK_MODULES([CUDA], [cuda-6.5 cudart-6.5],, [
|
||||
PKG_CHECK_MODULES([CUDA], [cuda-10.1],, [
|
||||
PKG_CHECK_MODULES([CUDA], [cuda-10.0],, [
|
||||
PKG_CHECK_MODULES([CUDA], [cuda-9.2],, [
|
||||
PKG_CHECK_MODULES([CUDA], [cuda-9.1],, [
|
||||
PKG_CHECK_MODULES([CUDA], [cuda-9.0],, [
|
||||
PKG_CHECK_MODULES([CUDA], [cuda-8.0],, [
|
||||
PKG_CHECK_MODULES([CUDA], [cuda-7.5],, [
|
||||
PKG_CHECK_MODULES([CUDA], [cuda-7.0],, [
|
||||
PKG_CHECK_MODULES([CUDA], [cuda-6.5],, [
|
||||
AC_MSG_WARN([Could not find cuda headers/libraries])])])])])])])])])])
|
||||
fi
|
||||
|
||||
HAVE_CUDA_H=no
|
||||
HAVE_CUDART_H=no
|
||||
save_CPPFLAGS="$CPPFLAGS"
|
||||
CPPFLAGS="$CUDA_CFLAGS $save_CPPFLAGS "
|
||||
AC_CHECK_HEADER([cuda.h], [HAVE_CUDA_H=yes],
|
||||
AC_MSG_WARN([Could not find cuda.h]))
|
||||
AC_CHECK_HEADER([cuda_runtime_api.h], [HAVE_CUDART_H=yes],
|
||||
AC_MSG_WARN([Could not find cuda_runtime_api.h]))
|
||||
CPPFLAGS=$save_CPPFLAGS
|
||||
|
||||
dnl libcuda and libcudart libraries
|
||||
save_LIBS="$LIBS"
|
||||
LIBS="$CUDA_LIBS $save_LIBS"
|
||||
HAVE_CUDART_LIB="no"
|
||||
AC_CHECK_LIB(cudart,cudaGetErrorString,[HAVE_CUDART_LIB="yes"], [
|
||||
AC_MSG_WARN([Could not find cudart library])])
|
||||
HAVE_CUDA_LIB="no"
|
||||
AC_CHECK_LIB(cuda,cuInit,[HAVE_CUDA_LIB="yes"], [
|
||||
AC_MSG_WARN([Could not find cuda library])])
|
||||
LIBS="$save_LIBS"
|
||||
])
|
||||
|
||||
dnl *** NVDEC ***
|
||||
translit(dnm, m, l) AM_CONDITIONAL(USE_NVDEC, true)
|
||||
AG_GST_CHECK_FEATURE(NVDEC, [nvdec], nvdec, [
|
||||
save_CPPFLAGS="$CPPFLAGS"
|
||||
CPPFLAGS="$CUDA_CFLAGS $save_CPPFLAGS"
|
||||
CPPFLAGS=$save_CPPFLAGS
|
||||
|
||||
HAVE_NVCUVID=no
|
||||
save_LIBS="$LIBS"
|
||||
LIBS="$CUDA_LIBS $save_LIBS"
|
||||
AC_CHECK_LIB(nvcuvid, cuvidCtxLock, [HAVE_NVCUVID=yes],
|
||||
AC_MSG_WARN([Could not find library nvcuvid]))
|
||||
LIBS="$save_LIBS"
|
||||
|
||||
if test "x$HAVE_NVCUVID" = "xyes"; then
|
||||
HAVE_NVDEC=yes
|
||||
else
|
||||
HAVE_NVDEC=no
|
||||
fi
|
||||
])
|
||||
|
||||
dnl *** NVENC ***
|
||||
translit(dnm, m, l) AM_CONDITIONAL(USE_NVENC, true)
|
||||
AG_GST_CHECK_FEATURE(NVENC, [NVIDIA Encode API], nvenc, [
|
||||
dnl libnvnidia-encode library
|
||||
HAVE_NVENCODE_LIB=no
|
||||
AC_ARG_VAR(NVENCODE_LIBS, [linker flags for nvidia-encode])
|
||||
saved_LIBS="$LIBS"
|
||||
LIBS="$NVENCODE_LIBS $saved_LIBS"
|
||||
AC_CHECK_LIB(nvidia-encode, NvEncodeAPICreateInstance, [HAVE_NVENCODE_LIB="yes"],
|
||||
AC_MSG_WARN([Could not find library nvidia-encode]))
|
||||
NVENCODE_LIBS="$NVENCODE_LIBS -lnvidia-encode"
|
||||
AC_SUBST(NVENCODE_LIBS)
|
||||
LIBS="$saved_LIBS"
|
||||
|
||||
dnl *** USE_NVCODEC ***
|
||||
translit(dnm, m, l) AM_CONDITIONAL(USE_NVCODEC, true)
|
||||
AG_GST_CHECK_FEATURE(NVCODEC, [NVIDIA Codec plugin], nvcodec, [
|
||||
USE_NVENC_GST_GL=no
|
||||
if test "x$HAVE_CUDA_H" = "xyes" \
|
||||
-a "x$HAVE_CUDART_H" = "xyes" \
|
||||
-a "x$HAVE_CUDA_LIB" = "xyes" \
|
||||
-a "x$HAVE_CUDART_LIB" = "xyes" \
|
||||
-a "x$HAVE_NVENCODE_LIB" = "xyes"; then
|
||||
HAVE_NVENC="yes"
|
||||
if test "x$HAVE_CUDA_H" = "xyes"; then
|
||||
HAVE_NVCODEC="yes"
|
||||
if test "x$GST_GL_HAVE_API_GL" = "x1"; then
|
||||
dnl cuda-gl interop header
|
||||
dnl cudaGL header
|
||||
save_CPPFLAGS="$CPPFLAGS"
|
||||
CPPFLAGS="$save_CPPFLAGS $CUDA_CFLAGS"
|
||||
AC_CHECK_HEADER([cuda_gl_interop.h], [
|
||||
USE_NVENC_GST_GL="yes"
|
||||
AC_DEFINE(HAVE_NVENC_GST_GL, [1] , [NVENC GStreamer OpenGL support available])
|
||||
AC_CHECK_HEADER([cudaGL.h], [
|
||||
USE_NVCODEC_GST_GL="yes"
|
||||
AC_DEFINE(HAVE_NVCODEC_GST_GL, [1] , [NVCODEC GStreamer OpenGL support available])
|
||||
], [], [
|
||||
/* missing headers in old cudaGL.h */
|
||||
#ifdef __APPLE__
|
||||
#include <OpenGL/gl.h>
|
||||
#else
|
||||
#include <GL/gl.h>
|
||||
#endif
|
||||
#include <cuda.h>
|
||||
])
|
||||
CPPFLAGS="$save_CPPFLAGS"
|
||||
fi
|
||||
else
|
||||
HAVE_NVENC="no"
|
||||
HAVE_NVCODEC="no"
|
||||
fi
|
||||
])
|
||||
AM_CONDITIONAL(USE_NVENC_GST_GL, test "x$USE_NVENC_GST_GL" = "xyes")
|
||||
AM_CONDITIONAL(USE_NVCODEC_GST_GL, test "x$USE_NVCODEC_GST_GL" = "xyes")
|
||||
|
||||
dnl check for tinyalsa
|
||||
translit(dnm, m, l) AM_CONDITIONAL(USE_TINYALSA, true)
|
||||
|
@ -2494,8 +2451,7 @@ sys/fbdev/Makefile
|
|||
sys/ipcpipeline/Makefile
|
||||
sys/kms/Makefile
|
||||
sys/msdk/Makefile
|
||||
sys/nvdec/Makefile
|
||||
sys/nvenc/Makefile
|
||||
sys/nvcodec/Makefile
|
||||
sys/opensles/Makefile
|
||||
sys/shm/Makefile
|
||||
sys/tinyalsa/Makefile
|
||||
|
|
|
@ -119,8 +119,7 @@ option('mplex', type : 'feature', value : 'auto', description : 'mplex audio/vid
|
|||
option('msdk', type : 'feature', value : 'auto', description : 'Intel Media SDK video encoder/decoder plugin')
|
||||
option('musepack', type : 'feature', value : 'auto', description : 'libmpcdec Musepack decoder plugin')
|
||||
option('neon', type : 'feature', value : 'auto', description : 'NEON HTTP source plugin')
|
||||
option('nvdec', type : 'feature', value : 'auto', description : 'NVIDIA GPU decoder plugin')
|
||||
option('nvenc', type : 'feature', value : 'auto', description : 'NVIDIA GPU encoder plugin')
|
||||
option('nvcodec', type : 'feature', value : 'auto', description : 'NVIDIA GPU codec plugin')
|
||||
option('ofa', type : 'feature', value : 'auto', description : 'Open Fingerprint Architecture library plugin')
|
||||
option('openal', type : 'feature', value : 'auto', description : 'OpenAL plugin')
|
||||
option('openexr', type : 'feature', value : 'auto', description : 'OpenEXR plugin')
|
||||
|
|
|
@ -94,16 +94,10 @@ else
|
|||
UVCH264_DIR=
|
||||
endif
|
||||
|
||||
if USE_NVDEC
|
||||
NVDEC_DIR=nvdec
|
||||
if USE_NVCODEC
|
||||
NVCODEC_DIR=nvcodec
|
||||
else
|
||||
NVDEC_DIR=
|
||||
endif
|
||||
|
||||
if USE_NVENC
|
||||
NVENC_DIR=nvenc
|
||||
else
|
||||
NVENC_DIR=
|
||||
NVCODEC_DIR=
|
||||
endif
|
||||
|
||||
if USE_TINYALSA
|
||||
|
@ -118,10 +112,10 @@ else
|
|||
MSDK_DIR=
|
||||
endif
|
||||
|
||||
SUBDIRS = $(ANDROID_MEDIA_DIR) $(APPLE_MEDIA_DIR) $(BLUEZ_DIR) $(D3DVIDEOSINK_DIR) $(DECKLINK_DIR) $(DIRECTSOUND_DIR) $(WINKS_DIR) $(DVB_DIR) $(FBDEV_DIR) $(IPCPIPELINE_DIR) $(KMS_DIR) $(OPENSLES_DIR) $(SHM_DIR) $(UVCH264_DIR) $(WININET_DIR) $(WINSCREENCAP_DIR) $(WASAPI_DIR) $(NVDEC_DIR) $(NVENC_DIR) $(TINYALSA_DIR) $(MSDK_DIR)
|
||||
SUBDIRS = $(ANDROID_MEDIA_DIR) $(APPLE_MEDIA_DIR) $(BLUEZ_DIR) $(D3DVIDEOSINK_DIR) $(DECKLINK_DIR) $(DIRECTSOUND_DIR) $(WINKS_DIR) $(DVB_DIR) $(FBDEV_DIR) $(IPCPIPELINE_DIR) $(KMS_DIR) $(OPENSLES_DIR) $(SHM_DIR) $(UVCH264_DIR) $(WININET_DIR) $(WINSCREENCAP_DIR) $(WASAPI_DIR) $(NVCODEC_DIR) $(TINYALSA_DIR) $(MSDK_DIR)
|
||||
|
||||
DIST_SUBDIRS = androidmedia applemedia bluez d3dvideosink decklink directsound dvb fbdev ipcpipeline kms dshowdecwrapper dshowsrcwrapper dshowvideosink \
|
||||
opensles shm uvch264 wasapi winks winscreencap \
|
||||
nvdec nvenc tinyalsa msdk
|
||||
nvcodec tinyalsa msdk
|
||||
|
||||
include $(top_srcdir)/common/parallel-subdirs.mak
|
||||
|
|
|
@ -13,6 +13,7 @@ subdir('fbdev')
|
|||
subdir('ipcpipeline')
|
||||
subdir('kms')
|
||||
subdir('msdk')
|
||||
subdir('nvcodec')
|
||||
subdir('opensles')
|
||||
subdir('shm')
|
||||
subdir('tinyalsa')
|
||||
|
@ -21,98 +22,3 @@ subdir('wasapi')
|
|||
subdir('winks')
|
||||
subdir('winscreencap')
|
||||
|
||||
# CUDA dependency
|
||||
cuda_dep = dependency('', required : false)
|
||||
cudart_dep = dependency('', required : false)
|
||||
cuda_libdir = ''
|
||||
cuda_incdir = ''
|
||||
|
||||
cuda_versions = [
|
||||
'10.1',
|
||||
'10.0',
|
||||
'9.2',
|
||||
'9.1',
|
||||
'9.0',
|
||||
'8.0',
|
||||
'7.5',
|
||||
'7.0',
|
||||
'6.5',
|
||||
]
|
||||
cuda_ver = ''
|
||||
|
||||
# FIXME: use break syntax when we use meson >= '0.49'
|
||||
foreach v : cuda_versions
|
||||
if cuda_ver == ''
|
||||
cuda_dep = dependency('cuda-' + v, required: false)
|
||||
cudart_dep = dependency('cudart-' + v, required: false)
|
||||
if cuda_dep.found() and cudart_dep.found()
|
||||
cuda_ver = v
|
||||
endif
|
||||
endif
|
||||
endforeach
|
||||
|
||||
if cuda_dep.found()
|
||||
cuda_header_found = cc.has_header('cuda.h', dependencies: cuda_dep)
|
||||
cuda_lib_found = cc.has_function('cuInit', dependencies: cuda_dep)
|
||||
if not cuda_header_found or not cuda_lib_found
|
||||
message ('Missing required header and/or function in cuda dependency')
|
||||
cuda_dep = dependency('', required : false)
|
||||
endif
|
||||
endif
|
||||
|
||||
if cudart_dep.found()
|
||||
cudart_header_found = cc.has_header('cuda_runtime_api.h', dependencies: cudart_dep)
|
||||
cudart_lib_found = cc.has_function('cudaGetErrorString', dependencies: cudart_dep)
|
||||
if not cudart_header_found or not cudart_lib_found
|
||||
message ('Missing required header and/or function in cudart dependency')
|
||||
cudart_dep = dependency('', required : false)
|
||||
endif
|
||||
endif
|
||||
|
||||
if not cuda_dep.found() or not cudart_dep.found()
|
||||
cuda_root = run_command(python3, '-c', 'import os; print(os.environ.get("CUDA_PATH"))').stdout().strip()
|
||||
if cuda_root != '' and cuda_root != 'None'
|
||||
if host_machine.system() == 'windows'
|
||||
arc = ''
|
||||
if build_machine.cpu_family() == 'x86_64'
|
||||
arc = 'x64'
|
||||
else
|
||||
arc = 'Win32'
|
||||
endif
|
||||
cuda_libdir = join_paths (cuda_root, 'lib', arc)
|
||||
else
|
||||
cuda_libdir = [join_paths (cuda_root, 'lib'), join_paths (cuda_root, 'lib', 'stubs'),
|
||||
join_paths (cuda_root, 'lib64'), join_paths (cuda_root, 'lib64', 'stubs')]
|
||||
endif
|
||||
cuda_incdir = join_paths (cuda_root, 'include')
|
||||
cuda_lib = cc.find_library('cuda', dirs: cuda_libdir, required: false)
|
||||
cudart_lib = cc.find_library('cudart', dirs: cuda_libdir, required: false)
|
||||
|
||||
if cuda_lib.found()
|
||||
cuda_header_found = cc.has_header('cuda.h', args: '-I' + cuda_incdir)
|
||||
cuda_lib_found = cc.has_function('cuInit', dependencies: cuda_lib)
|
||||
if cuda_header_found and cuda_lib_found
|
||||
cuda_dep = declare_dependency(include_directories: include_directories(cuda_incdir),
|
||||
dependencies: cuda_lib)
|
||||
endif
|
||||
endif
|
||||
|
||||
if cudart_lib.found()
|
||||
cudart_header_found = cc.has_header('cuda_runtime_api.h', args: '-I' + cuda_incdir)
|
||||
cudart_lib_found = cc.has_function('cudaGetErrorString', dependencies: cudart_lib)
|
||||
if cudart_header_found and cudart_lib_found
|
||||
cudart_dep = declare_dependency(dependencies: cudart_lib)
|
||||
endif
|
||||
endif
|
||||
|
||||
endif
|
||||
endif
|
||||
|
||||
if cuda_dep.found() and cudart_dep.found()
|
||||
subdir('nvdec')
|
||||
subdir('nvenc')
|
||||
elif get_option('nvdec').enabled()
|
||||
error('The nvdec plugin was enabled explicitly, but required CUDA dependencies were not found.')
|
||||
elif get_option('nvenc').enabled()
|
||||
error('The nvenc plugin was enabled explicitly, but required CUDA dependencies were not found.')
|
||||
endif
|
||||
|
|
46
sys/nvcodec/Makefile.am
Normal file
46
sys/nvcodec/Makefile.am
Normal file
|
@ -0,0 +1,46 @@
|
|||
plugin_LTLIBRARIES = libgstnvcodec.la
|
||||
|
||||
libgstnvcodec_la_SOURCES = \
|
||||
plugin.c \
|
||||
gstnvenc.c \
|
||||
gstnvbaseenc.c \
|
||||
gstnvh264enc.c \
|
||||
gstnvh265enc.c \
|
||||
gstcudaloader.c
|
||||
|
||||
if USE_NVCODEC_GST_GL
|
||||
libgstnvcodec_la_SOURCES += \
|
||||
gstnvdec.c \
|
||||
gstcuvidloader.c
|
||||
endif
|
||||
|
||||
noinst_HEADERS = \
|
||||
gstnvdec.h \
|
||||
gstnvenc.h \
|
||||
gstcuvidloader.h \
|
||||
gstnvbaseenc.h \
|
||||
gstnvh264enc.h \
|
||||
gstnvh265enc.h \
|
||||
nvEncodeAPI.h \
|
||||
cuviddec.h \
|
||||
nvcuvid.h \
|
||||
gstcuvidloader.h
|
||||
|
||||
libgstnvcodec_la_CFLAGS = \
|
||||
$(GST_PLUGINS_BAD_CFLAGS) \
|
||||
$(GST_PBUTILS_CFLAGS) \
|
||||
$(GST_VIDEO_CFLAGS) \
|
||||
$(GST_CFLAGS) \
|
||||
$(CUDA_CFLAGS)
|
||||
|
||||
libgstnvcodec_la_LIBADD = \
|
||||
$(GST_PBUTILS_LIBS) \
|
||||
$(GST_VIDEO_LIBS) \
|
||||
$(GST_LIBS) \
|
||||
$(GMODULE_NO_EXPORT_LIBS)
|
||||
|
||||
if USE_NVCODEC_GST_GL
|
||||
libgstnvcodec_la_CFLAGS += $(GST_GL_CFLAGS)
|
||||
libgstnvcodec_la_LIBADD += $(GST_GL_LIBS)
|
||||
endif
|
||||
libgstnvcodec_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
|
331
sys/nvcodec/gstcudaloader.c
Normal file
331
sys/nvcodec/gstcudaloader.c
Normal file
|
@ -0,0 +1,331 @@
|
|||
/* GStreamer
|
||||
* Copyright (C) 2019 Seungha Yang <seungha.yang@navercorp.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "gstcudaloader.h"
|
||||
#include <gmodule.h>
|
||||
|
||||
#ifndef G_OS_WIN32
|
||||
#define CUDA_LIBNAME "libcuda.so.1"
|
||||
#else
|
||||
#define CUDA_LIBNAME "nvcuda.dll"
|
||||
#endif
|
||||
|
||||
#define LOAD_SYMBOL(name,func) G_STMT_START { \
|
||||
if (!g_module_symbol (module, G_STRINGIFY (name), (gpointer *) &vtable->func)) { \
|
||||
GST_ERROR ("Failed to load '%s' from %s, %s", G_STRINGIFY (name), filename, g_module_error()); \
|
||||
goto error; \
|
||||
} \
|
||||
} G_STMT_END;
|
||||
|
||||
typedef struct _GstNvCodecCudaVTable
|
||||
{
|
||||
gboolean loaded;
|
||||
|
||||
CUresult (*CuInit) (unsigned int Flags);
|
||||
CUresult (*CuGetErrorName) (CUresult error, const char **pStr);
|
||||
CUresult (*CuGetErrorString) (CUresult error, const char **pStr);
|
||||
|
||||
CUresult (*CuCtxCreate) (CUcontext * pctx, unsigned int flags,
|
||||
CUdevice dev);
|
||||
CUresult (*CuCtxDestroy) (CUcontext ctx);
|
||||
CUresult (*CuCtxPopCurrent) (CUcontext * pctx);
|
||||
CUresult (*CuCtxPushCurrent) (CUcontext ctx);
|
||||
|
||||
CUresult (*CuGraphicsMapResources) (unsigned int count,
|
||||
CUgraphicsResource * resources, CUstream hStream);
|
||||
CUresult (*CuGraphicsUnmapResources) (unsigned int count,
|
||||
CUgraphicsResource * resources, CUstream hStream);
|
||||
CUresult (*CuGraphicsSubResourceGetMappedArray) (CUarray * pArray,
|
||||
CUgraphicsResource resource, unsigned int arrayIndex,
|
||||
unsigned int mipLevel);
|
||||
CUresult (*CuGraphicsResourceGetMappedPointer) (CUdeviceptr * pDevPtr,
|
||||
size_t * pSize, CUgraphicsResource resource);
|
||||
CUresult (*CuGraphicsUnregisterResource) (CUgraphicsResource resource);
|
||||
|
||||
CUresult (*CuMemAlloc) (CUdeviceptr * dptr, unsigned int bytesize);
|
||||
CUresult (*CuMemAllocPitch) (CUdeviceptr * dptr, size_t * pPitch,
|
||||
size_t WidthInBytes, size_t Height, unsigned int ElementSizeBytes);
|
||||
CUresult (*CuMemcpy2D) (const CUDA_MEMCPY2D * pCopy);
|
||||
CUresult (*CuMemFree) (CUdeviceptr dptr);
|
||||
|
||||
CUresult (*CuDeviceGet) (CUdevice * device, int ordinal);
|
||||
CUresult (*CuDeviceGetCount) (int *count);
|
||||
CUresult (*CuDeviceGetName) (char *name, int len, CUdevice dev);
|
||||
CUresult (*CuDeviceGetAttribute) (int *pi, CUdevice_attribute attrib,
|
||||
CUdevice dev);
|
||||
|
||||
CUresult (*CuGraphicsGLRegisterImage) (CUgraphicsResource * pCudaResource,
|
||||
unsigned int image, unsigned int target, unsigned int Flags);
|
||||
CUresult (*CuGraphicsGLRegisterBuffer) (CUgraphicsResource * pCudaResource,
|
||||
unsigned int buffer, unsigned int Flags);
|
||||
} GstNvCodecCudaVTable;
|
||||
|
||||
static GstNvCodecCudaVTable gst_cuda_vtable = { 0, };
|
||||
|
||||
gboolean
|
||||
gst_cuda_load_library (void)
|
||||
{
|
||||
GModule *module;
|
||||
const gchar *filename = CUDA_LIBNAME;
|
||||
GstNvCodecCudaVTable *vtable;
|
||||
|
||||
if (gst_cuda_vtable.loaded)
|
||||
return TRUE;
|
||||
|
||||
module = g_module_open (filename, G_MODULE_BIND_LAZY);
|
||||
if (module == NULL) {
|
||||
GST_ERROR ("Could not open library %s, %s", filename, g_module_error ());
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
vtable = &gst_cuda_vtable;
|
||||
|
||||
/* cuda.h */
|
||||
LOAD_SYMBOL (cuInit, CuInit);
|
||||
LOAD_SYMBOL (cuGetErrorName, CuGetErrorName);
|
||||
LOAD_SYMBOL (cuGetErrorString, CuGetErrorString);
|
||||
LOAD_SYMBOL (cuCtxCreate, CuCtxCreate);
|
||||
LOAD_SYMBOL (cuCtxDestroy, CuCtxDestroy);
|
||||
LOAD_SYMBOL (cuCtxPopCurrent, CuCtxPopCurrent);
|
||||
LOAD_SYMBOL (cuCtxPushCurrent, CuCtxPushCurrent);
|
||||
|
||||
LOAD_SYMBOL (cuGraphicsMapResources, CuGraphicsMapResources);
|
||||
LOAD_SYMBOL (cuGraphicsUnmapResources, CuGraphicsUnmapResources);
|
||||
LOAD_SYMBOL (cuGraphicsSubResourceGetMappedArray,
|
||||
CuGraphicsSubResourceGetMappedArray);
|
||||
LOAD_SYMBOL (cuGraphicsResourceGetMappedPointer,
|
||||
CuGraphicsResourceGetMappedPointer);
|
||||
LOAD_SYMBOL (cuGraphicsUnregisterResource, CuGraphicsUnregisterResource);
|
||||
|
||||
LOAD_SYMBOL (cuMemAlloc, CuMemAlloc);
|
||||
LOAD_SYMBOL (cuMemAllocPitch, CuMemAllocPitch);
|
||||
LOAD_SYMBOL (cuMemcpy2D, CuMemcpy2D);
|
||||
LOAD_SYMBOL (cuMemFree, CuMemFree);
|
||||
|
||||
LOAD_SYMBOL (cuDeviceGet, CuDeviceGet);
|
||||
LOAD_SYMBOL (cuDeviceGetCount, CuDeviceGetCount);
|
||||
LOAD_SYMBOL (cuDeviceGetName, CuDeviceGetName);
|
||||
LOAD_SYMBOL (cuDeviceGetAttribute, CuDeviceGetAttribute);
|
||||
|
||||
/* cudaGL.h */
|
||||
LOAD_SYMBOL (cuGraphicsGLRegisterImage, CuGraphicsGLRegisterImage);
|
||||
LOAD_SYMBOL (cuGraphicsGLRegisterBuffer, CuGraphicsGLRegisterBuffer);
|
||||
|
||||
vtable->loaded = TRUE;
|
||||
|
||||
return TRUE;
|
||||
|
||||
error:
|
||||
g_module_close (module);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
CUresult
|
||||
CuInit (unsigned int Flags)
|
||||
{
|
||||
g_assert (gst_cuda_vtable.CuInit != NULL);
|
||||
|
||||
return gst_cuda_vtable.CuInit (Flags);
|
||||
}
|
||||
|
||||
CUresult
|
||||
CuGetErrorName (CUresult error, const char **pStr)
|
||||
{
|
||||
g_assert (gst_cuda_vtable.CuGetErrorName != NULL);
|
||||
|
||||
return gst_cuda_vtable.CuGetErrorName (error, pStr);
|
||||
}
|
||||
|
||||
CUresult
|
||||
CuGetErrorString (CUresult error, const char **pStr)
|
||||
{
|
||||
g_assert (gst_cuda_vtable.CuGetErrorString != NULL);
|
||||
|
||||
return gst_cuda_vtable.CuGetErrorString (error, pStr);
|
||||
}
|
||||
|
||||
CUresult
|
||||
CuCtxCreate (CUcontext * pctx, unsigned int flags, CUdevice dev)
|
||||
{
|
||||
g_assert (gst_cuda_vtable.CuCtxCreate != NULL);
|
||||
|
||||
return gst_cuda_vtable.CuCtxCreate (pctx, flags, dev);
|
||||
}
|
||||
|
||||
CUresult
|
||||
CuCtxDestroy (CUcontext ctx)
|
||||
{
|
||||
g_assert (gst_cuda_vtable.CuCtxDestroy != NULL);
|
||||
|
||||
return gst_cuda_vtable.CuCtxDestroy (ctx);
|
||||
}
|
||||
|
||||
CUresult
|
||||
CuCtxPopCurrent (CUcontext * pctx)
|
||||
{
|
||||
g_assert (gst_cuda_vtable.CuCtxPopCurrent != NULL);
|
||||
|
||||
return gst_cuda_vtable.CuCtxPopCurrent (pctx);
|
||||
}
|
||||
|
||||
CUresult
|
||||
CuCtxPushCurrent (CUcontext ctx)
|
||||
{
|
||||
g_assert (gst_cuda_vtable.CuCtxPushCurrent != NULL);
|
||||
|
||||
return gst_cuda_vtable.CuCtxPushCurrent (ctx);
|
||||
}
|
||||
|
||||
CUresult
|
||||
CuGraphicsMapResources (unsigned int count, CUgraphicsResource * resources,
|
||||
CUstream hStream)
|
||||
{
|
||||
g_assert (gst_cuda_vtable.CuGraphicsMapResources != NULL);
|
||||
|
||||
return gst_cuda_vtable.CuGraphicsMapResources (count, resources, hStream);
|
||||
}
|
||||
|
||||
CUresult
|
||||
CuGraphicsUnmapResources (unsigned int count, CUgraphicsResource * resources,
|
||||
CUstream hStream)
|
||||
{
|
||||
g_assert (gst_cuda_vtable.CuGraphicsUnmapResources != NULL);
|
||||
|
||||
return gst_cuda_vtable.CuGraphicsUnmapResources (count, resources, hStream);
|
||||
}
|
||||
|
||||
CUresult
|
||||
CuGraphicsSubResourceGetMappedArray (CUarray * pArray,
|
||||
CUgraphicsResource resource, unsigned int arrayIndex, unsigned int mipLevel)
|
||||
{
|
||||
g_assert (gst_cuda_vtable.CuGraphicsSubResourceGetMappedArray != NULL);
|
||||
|
||||
return gst_cuda_vtable.CuGraphicsSubResourceGetMappedArray (pArray, resource,
|
||||
arrayIndex, mipLevel);
|
||||
}
|
||||
|
||||
CUresult
|
||||
CuGraphicsResourceGetMappedPointer (CUdeviceptr * pDevPtr, size_t * pSize,
|
||||
CUgraphicsResource resource)
|
||||
{
|
||||
g_assert (gst_cuda_vtable.CuGraphicsResourceGetMappedPointer != NULL);
|
||||
|
||||
return gst_cuda_vtable.CuGraphicsResourceGetMappedPointer (pDevPtr, pSize,
|
||||
resource);
|
||||
}
|
||||
|
||||
CUresult
|
||||
CuGraphicsUnregisterResource (CUgraphicsResource resource)
|
||||
{
|
||||
g_assert (gst_cuda_vtable.CuGraphicsUnregisterResource != NULL);
|
||||
|
||||
return gst_cuda_vtable.CuGraphicsUnregisterResource (resource);
|
||||
}
|
||||
|
||||
CUresult
|
||||
CuMemAlloc (CUdeviceptr * dptr, unsigned int bytesize)
|
||||
{
|
||||
g_assert (gst_cuda_vtable.CuMemAlloc != NULL);
|
||||
|
||||
return gst_cuda_vtable.CuMemAlloc (dptr, bytesize);
|
||||
}
|
||||
|
||||
CUresult
|
||||
CuMemAllocPitch (CUdeviceptr * dptr, size_t * pPitch, size_t WidthInBytes,
|
||||
size_t Height, unsigned int ElementSizeBytes)
|
||||
{
|
||||
g_assert (gst_cuda_vtable.CuMemAllocPitch != NULL);
|
||||
|
||||
return gst_cuda_vtable.CuMemAllocPitch (dptr, pPitch, WidthInBytes, Height,
|
||||
ElementSizeBytes);
|
||||
}
|
||||
|
||||
CUresult
|
||||
CuMemcpy2D (const CUDA_MEMCPY2D * pCopy)
|
||||
{
|
||||
g_assert (gst_cuda_vtable.CuMemcpy2D != NULL);
|
||||
|
||||
return gst_cuda_vtable.CuMemcpy2D (pCopy);
|
||||
}
|
||||
|
||||
CUresult
|
||||
CuMemFree (CUdeviceptr dptr)
|
||||
{
|
||||
g_assert (gst_cuda_vtable.CuMemFree != NULL);
|
||||
|
||||
return gst_cuda_vtable.CuMemFree (dptr);
|
||||
}
|
||||
|
||||
CUresult
|
||||
CuDeviceGet (CUdevice * device, int ordinal)
|
||||
{
|
||||
g_assert (gst_cuda_vtable.CuDeviceGet != NULL);
|
||||
|
||||
return gst_cuda_vtable.CuDeviceGet (device, ordinal);
|
||||
}
|
||||
|
||||
CUresult
|
||||
CuDeviceGetCount (int *count)
|
||||
{
|
||||
g_assert (gst_cuda_vtable.CuDeviceGetCount != NULL);
|
||||
|
||||
return gst_cuda_vtable.CuDeviceGetCount (count);
|
||||
}
|
||||
|
||||
CUresult
|
||||
CuDeviceGetName (char *name, int len, CUdevice dev)
|
||||
{
|
||||
g_assert (gst_cuda_vtable.CuDeviceGetName != NULL);
|
||||
|
||||
return gst_cuda_vtable.CuDeviceGetName (name, len, dev);
|
||||
}
|
||||
|
||||
CUresult
|
||||
CuDeviceGetAttribute (int *pi, CUdevice_attribute attrib, CUdevice dev)
|
||||
{
|
||||
g_assert (gst_cuda_vtable.CuDeviceGetAttribute != NULL);
|
||||
|
||||
return gst_cuda_vtable.CuDeviceGetAttribute (pi, attrib, dev);
|
||||
}
|
||||
|
||||
/* cudaGL.h */
|
||||
CUresult
|
||||
CuGraphicsGLRegisterImage (CUgraphicsResource * pCudaResource,
|
||||
unsigned int image, unsigned int target, unsigned int Flags)
|
||||
{
|
||||
g_assert (gst_cuda_vtable.CuGraphicsGLRegisterImage != NULL);
|
||||
|
||||
return gst_cuda_vtable.CuGraphicsGLRegisterImage (pCudaResource, image,
|
||||
target, Flags);
|
||||
}
|
||||
|
||||
CUresult
|
||||
CuGraphicsGLRegisterBuffer (CUgraphicsResource * pCudaResource,
|
||||
unsigned int buffer, unsigned int Flags)
|
||||
{
|
||||
g_assert (gst_cuda_vtable.CuGraphicsGLRegisterBuffer != NULL);
|
||||
|
||||
return gst_cuda_vtable.CuGraphicsGLRegisterBuffer (pCudaResource, buffer,
|
||||
Flags);
|
||||
}
|
128
sys/nvcodec/gstcudaloader.h
Normal file
128
sys/nvcodec/gstcudaloader.h
Normal file
|
@ -0,0 +1,128 @@
|
|||
/* GStreamer
|
||||
* Copyright (C) 2019 Seungha Yang <seungha.yang@navercorp.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef __GST_CUDA_LOADER_H__
|
||||
#define __GST_CUDA_LOADER_H__
|
||||
|
||||
#include <gst/gst.h>
|
||||
#include <cuda.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
gboolean gst_cuda_load_library (void);
|
||||
|
||||
/* cuda.h */
|
||||
G_GNUC_INTERNAL
|
||||
CUresult CuInit (unsigned int Flags);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
CUresult CuGetErrorName (CUresult error,
|
||||
const char **pStr);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
CUresult CuGetErrorString (CUresult error,
|
||||
const char **pStr);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
CUresult CuCtxCreate (CUcontext * pctx,
|
||||
unsigned int flags,
|
||||
CUdevice dev);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
CUresult CuCtxDestroy (CUcontext ctx);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
CUresult CuCtxPopCurrent (CUcontext * pctx);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
CUresult CuCtxPushCurrent (CUcontext ctx);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
CUresult CuGraphicsMapResources (unsigned int count,
|
||||
CUgraphicsResource * resources,
|
||||
CUstream hStream);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
CUresult CuGraphicsUnmapResources (unsigned int count,
|
||||
CUgraphicsResource * resources,
|
||||
CUstream hStream);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
CUresult CuGraphicsSubResourceGetMappedArray (CUarray * pArray,
|
||||
CUgraphicsResource resource,
|
||||
unsigned int arrayIndex,
|
||||
unsigned int mipLevel);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
CUresult CuGraphicsResourceGetMappedPointer (CUdeviceptr * pDevPtr,
|
||||
size_t * pSize,
|
||||
CUgraphicsResource resource);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
CUresult CuGraphicsUnregisterResource (CUgraphicsResource resource);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
CUresult CuMemAlloc (CUdeviceptr * dptr,
|
||||
unsigned int bytesize);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
CUresult CuMemAllocPitch (CUdeviceptr * dptr,
|
||||
size_t * pPitch,
|
||||
size_t WidthInBytes,
|
||||
size_t Height,
|
||||
unsigned int ElementSizeBytes);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
CUresult CuMemcpy2D (const CUDA_MEMCPY2D * pCopy);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
CUresult CuMemFree (CUdeviceptr dptr);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
CUresult CuDeviceGet (CUdevice * device,
|
||||
int ordinal);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
CUresult CuDeviceGetCount (int *count);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
CUresult CuDeviceGetName (char *name,
|
||||
int len,
|
||||
CUdevice dev);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
CUresult CuDeviceGetAttribute (int *pi,
|
||||
CUdevice_attribute attrib,
|
||||
CUdevice dev);
|
||||
|
||||
/* cudaGL.h */
|
||||
G_GNUC_INTERNAL
|
||||
CUresult CuGraphicsGLRegisterImage (CUgraphicsResource * pCudaResource,
|
||||
unsigned int image,
|
||||
unsigned int target,
|
||||
unsigned int Flags);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
CUresult CuGraphicsGLRegisterBuffer (CUgraphicsResource * pCudaResource,
|
||||
unsigned int buffer,
|
||||
unsigned int Flags);
|
||||
|
||||
G_END_DECLS
|
||||
#endif /* __GST_CUDA_LOADER_H__ */
|
203
sys/nvcodec/gstcuvidloader.c
Normal file
203
sys/nvcodec/gstcuvidloader.c
Normal file
|
@ -0,0 +1,203 @@
|
|||
/* GStreamer
|
||||
* Copyright (C) 2019 Seungha Yang <seungha.yang@navercorp.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "gstcuvidloader.h"
|
||||
#include <gmodule.h>
|
||||
|
||||
#ifdef G_OS_WIN32
|
||||
#define NVCUVID_LIBNAME "nvcuvid.dll"
|
||||
#else
|
||||
#define NVCUVID_LIBNAME "libnvcuvid.so.1"
|
||||
#endif
|
||||
|
||||
#define LOAD_SYMBOL(name,func) G_STMT_START { \
|
||||
if (!g_module_symbol (module, G_STRINGIFY (name), (gpointer *) &vtable->func)) { \
|
||||
GST_ERROR ("Failed to load '%s' from %s, %s", G_STRINGIFY (name), filename, g_module_error()); \
|
||||
goto error; \
|
||||
} \
|
||||
} G_STMT_END;
|
||||
|
||||
typedef struct _GstnvdecCuvidVTable
|
||||
{
|
||||
gboolean loaded;
|
||||
|
||||
CUresult (*CuvidCtxLockCreate) (CUvideoctxlock * pLock, CUcontext ctx);
|
||||
CUresult (*CuvidCtxLockDestroy) (CUvideoctxlock lck);
|
||||
CUresult (*CuvidCtxLock) (CUvideoctxlock lck, unsigned int reserved_flags);
|
||||
CUresult (*CuvidCtxUnlock) (CUvideoctxlock lck,
|
||||
unsigned int reserved_flags);
|
||||
CUresult (*CuvidCreateDecoder) (CUvideodecoder * phDecoder,
|
||||
CUVIDDECODECREATEINFO * pdci);
|
||||
CUresult (*CuvidDestroyDecoder) (CUvideodecoder hDecoder);
|
||||
CUresult (*CuvidDecodePicture) (CUvideodecoder hDecoder,
|
||||
CUVIDPICPARAMS * pPicParams);
|
||||
CUresult (*CuvidCreateVideoParser) (CUvideoparser * pObj,
|
||||
CUVIDPARSERPARAMS * pParams);
|
||||
CUresult (*CuvidParseVideoData) (CUvideoparser obj,
|
||||
CUVIDSOURCEDATAPACKET * pPacket);
|
||||
CUresult (*CuvidDestroyVideoParser) (CUvideoparser obj);
|
||||
CUresult (*CuvidMapVideoFrame) (CUvideodecoder hDecoder, int nPicIdx,
|
||||
guintptr * pDevPtr, unsigned int *pPitch, CUVIDPROCPARAMS * pVPP);
|
||||
CUresult (*CuvidUnmapVideoFrame) (CUvideodecoder hDecoder, guintptr DevPtr);
|
||||
} GstnvdecCuvidVTable;
|
||||
|
||||
static GstnvdecCuvidVTable gst_cuvid_vtable = { 0, };
|
||||
|
||||
gboolean
|
||||
gst_cuvid_load_library (void)
|
||||
{
|
||||
GModule *module;
|
||||
const gchar *filename = NVCUVID_LIBNAME;
|
||||
GstnvdecCuvidVTable *vtable;
|
||||
|
||||
if (gst_cuvid_vtable.loaded)
|
||||
return TRUE;
|
||||
|
||||
module = g_module_open (filename, G_MODULE_BIND_LAZY);
|
||||
if (module == NULL) {
|
||||
GST_ERROR ("Could not open library %s, %s", filename, g_module_error ());
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
vtable = &gst_cuvid_vtable;
|
||||
|
||||
LOAD_SYMBOL (cuvidCtxLockCreate, CuvidCtxLockCreate);
|
||||
LOAD_SYMBOL (cuvidCtxLockDestroy, CuvidCtxLockDestroy);
|
||||
LOAD_SYMBOL (cuvidCtxLock, CuvidCtxLock);
|
||||
LOAD_SYMBOL (cuvidCtxUnlock, CuvidCtxUnlock);
|
||||
LOAD_SYMBOL (cuvidCreateDecoder, CuvidCreateDecoder);
|
||||
LOAD_SYMBOL (cuvidDestroyDecoder, CuvidDestroyDecoder);
|
||||
LOAD_SYMBOL (cuvidDecodePicture, CuvidDecodePicture);
|
||||
LOAD_SYMBOL (cuvidCreateVideoParser, CuvidCreateVideoParser);
|
||||
LOAD_SYMBOL (cuvidParseVideoData, CuvidParseVideoData);
|
||||
LOAD_SYMBOL (cuvidDestroyVideoParser, CuvidDestroyVideoParser);
|
||||
LOAD_SYMBOL (cuvidMapVideoFrame, CuvidMapVideoFrame);
|
||||
LOAD_SYMBOL (cuvidUnmapVideoFrame, CuvidUnmapVideoFrame);
|
||||
|
||||
vtable->loaded = TRUE;
|
||||
|
||||
return TRUE;
|
||||
|
||||
error:
|
||||
g_module_close (module);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
CUresult
|
||||
CuvidCtxLockCreate (CUvideoctxlock * pLock, CUcontext ctx)
|
||||
{
|
||||
g_assert (gst_cuvid_vtable.CuvidCtxLockCreate != NULL);
|
||||
|
||||
return gst_cuvid_vtable.CuvidCtxLockCreate (pLock, ctx);
|
||||
}
|
||||
|
||||
CUresult
|
||||
CuvidCtxLockDestroy (CUvideoctxlock lck)
|
||||
{
|
||||
g_assert (gst_cuvid_vtable.CuvidCtxLockDestroy != NULL);
|
||||
|
||||
return gst_cuvid_vtable.CuvidCtxLockDestroy (lck);
|
||||
}
|
||||
|
||||
CUresult
|
||||
CuvidCtxLock (CUvideoctxlock lck, unsigned int reserved_flags)
|
||||
{
|
||||
g_assert (gst_cuvid_vtable.CuvidCtxLock != NULL);
|
||||
|
||||
return gst_cuvid_vtable.CuvidCtxLock (lck, reserved_flags);
|
||||
}
|
||||
|
||||
CUresult
|
||||
CuvidCtxUnlock (CUvideoctxlock lck, unsigned int reserved_flags)
|
||||
{
|
||||
g_assert (gst_cuvid_vtable.CuvidCtxLockDestroy != NULL);
|
||||
|
||||
return gst_cuvid_vtable.CuvidCtxUnlock (lck, reserved_flags);
|
||||
}
|
||||
|
||||
CUresult
|
||||
CuvidCreateDecoder (CUvideodecoder * phDecoder, CUVIDDECODECREATEINFO * pdci)
|
||||
{
|
||||
g_assert (gst_cuvid_vtable.CuvidCreateDecoder != NULL);
|
||||
|
||||
return gst_cuvid_vtable.CuvidCreateDecoder (phDecoder, pdci);
|
||||
}
|
||||
|
||||
CUresult
|
||||
CuvidDestroyDecoder (CUvideodecoder hDecoder)
|
||||
{
|
||||
g_assert (gst_cuvid_vtable.CuvidDestroyDecoder != NULL);
|
||||
|
||||
return gst_cuvid_vtable.CuvidDestroyDecoder (hDecoder);
|
||||
}
|
||||
|
||||
CUresult
|
||||
CuvidDecodePicture (CUvideodecoder hDecoder, CUVIDPICPARAMS * pPicParams)
|
||||
{
|
||||
g_assert (gst_cuvid_vtable.CuvidDecodePicture != NULL);
|
||||
|
||||
return gst_cuvid_vtable.CuvidDecodePicture (hDecoder, pPicParams);
|
||||
}
|
||||
|
||||
CUresult
|
||||
CuvidCreateVideoParser (CUvideoparser * pObj, CUVIDPARSERPARAMS * pParams)
|
||||
{
|
||||
g_assert (gst_cuvid_vtable.CuvidCreateVideoParser != NULL);
|
||||
|
||||
return gst_cuvid_vtable.CuvidCreateVideoParser (pObj, pParams);
|
||||
}
|
||||
|
||||
CUresult
|
||||
CuvidParseVideoData (CUvideoparser obj, CUVIDSOURCEDATAPACKET * pPacket)
|
||||
{
|
||||
g_assert (gst_cuvid_vtable.CuvidParseVideoData != NULL);
|
||||
|
||||
return gst_cuvid_vtable.CuvidParseVideoData (obj, pPacket);
|
||||
}
|
||||
|
||||
CUresult
|
||||
CuvidDestroyVideoParser (CUvideoparser obj)
|
||||
{
|
||||
g_assert (gst_cuvid_vtable.CuvidDestroyVideoParser != NULL);
|
||||
|
||||
return gst_cuvid_vtable.CuvidDestroyVideoParser (obj);
|
||||
}
|
||||
|
||||
CUresult
|
||||
CuvidMapVideoFrame (CUvideodecoder hDecoder, int nPicIdx,
|
||||
guintptr * pDevPtr, unsigned int *pPitch, CUVIDPROCPARAMS * pVPP)
|
||||
{
|
||||
g_assert (gst_cuvid_vtable.CuvidMapVideoFrame != NULL);
|
||||
|
||||
return gst_cuvid_vtable.CuvidMapVideoFrame (hDecoder, nPicIdx, pDevPtr,
|
||||
pPitch, pVPP);
|
||||
}
|
||||
|
||||
CUresult
|
||||
CuvidUnmapVideoFrame (CUvideodecoder hDecoder, guintptr DevPtr)
|
||||
{
|
||||
g_assert (gst_cuvid_vtable.CuvidUnmapVideoFrame != NULL);
|
||||
|
||||
return gst_cuvid_vtable.CuvidUnmapVideoFrame (hDecoder, DevPtr);
|
||||
}
|
80
sys/nvcodec/gstcuvidloader.h
Normal file
80
sys/nvcodec/gstcuvidloader.h
Normal file
|
@ -0,0 +1,80 @@
|
|||
/* GStreamer
|
||||
* Copyright (C) 2019 Seungha Yang <seungha.yang@navercorp.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef __GST_CUVID_LOADER_H__
|
||||
#define __GST_CUVID_LOADER_H__
|
||||
|
||||
#include <gst/gst.h>
|
||||
#include "nvcuvid.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
/* cuvid.h */
|
||||
G_GNUC_INTERNAL
|
||||
gboolean gst_cuvid_load_library (void);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
CUresult CuvidCtxLockCreate (CUvideoctxlock * pLock, CUcontext ctx);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
CUresult CuvidCtxLockDestroy (CUvideoctxlock lck);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
CUresult CuvidCtxLock (CUvideoctxlock lck,
|
||||
unsigned int reserved_flags);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
CUresult CuvidCtxUnlock (CUvideoctxlock lck,
|
||||
unsigned int reserved_flags);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
CUresult CuvidCreateDecoder (CUvideodecoder * phDecoder,
|
||||
CUVIDDECODECREATEINFO * pdci);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
CUresult CuvidDestroyDecoder (CUvideodecoder hDecoder);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
CUresult CuvidDecodePicture (CUvideodecoder hDecoder,
|
||||
CUVIDPICPARAMS * pPicParams);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
CUresult CuvidCreateVideoParser (CUvideoparser * pObj,
|
||||
CUVIDPARSERPARAMS * pParams);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
CUresult CuvidParseVideoData (CUvideoparser obj,
|
||||
CUVIDSOURCEDATAPACKET * pPacket);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
CUresult CuvidDestroyVideoParser (CUvideoparser obj);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
CUresult CuvidMapVideoFrame (CUvideodecoder hDecoder,
|
||||
int nPicIdx,
|
||||
guintptr * pDevPtr,
|
||||
unsigned int *pPitch,
|
||||
CUVIDPROCPARAMS * pVPP);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
CUresult CuvidUnmapVideoFrame (CUvideodecoder hDecoder,
|
||||
guintptr DevPtr);
|
||||
|
||||
G_END_DECLS
|
||||
#endif /* __GST_CUVID_LOADER_H__ */
|
|
@ -29,12 +29,15 @@
|
|||
|
||||
#define GST_CAT_DEFAULT gst_nvenc_debug
|
||||
|
||||
#if HAVE_NVENC_GST_GL
|
||||
#include <cuda.h>
|
||||
#include <cuda_runtime_api.h>
|
||||
#include <cuda_gl_interop.h>
|
||||
#include <cudaGL.h>
|
||||
#if HAVE_NVCODEC_GST_GL
|
||||
#include <gst/gl/gl.h>
|
||||
/* missing headers in old cudaGL.h */
|
||||
#ifdef __APPLE__
|
||||
#include <OpenGL/gl.h>
|
||||
#else
|
||||
#include <GL/gl.h>
|
||||
#endif
|
||||
#include <cudaGL.h>
|
||||
#endif
|
||||
|
||||
/* TODO:
|
||||
|
@ -168,7 +171,7 @@ enum
|
|||
* some period of time. */
|
||||
G_LOCK_DEFINE_STATIC (initialization_lock);
|
||||
|
||||
#if HAVE_NVENC_GST_GL
|
||||
#if HAVE_NVCODEC_GST_GL
|
||||
struct gl_input_resource
|
||||
{
|
||||
GstGLMemory *gl_mem[GST_VIDEO_MAX_PLANES];
|
||||
|
@ -439,7 +442,7 @@ gst_nv_base_enc_open (GstVideoEncoder * enc)
|
|||
static void
|
||||
gst_nv_base_enc_set_context (GstElement * element, GstContext * context)
|
||||
{
|
||||
#if HAVE_NVENC_GST_GL
|
||||
#if HAVE_NVCODEC_GST_GL
|
||||
GstNvBaseEnc *nvenc = GST_NV_BASE_ENC (element);
|
||||
|
||||
gst_gl_handle_set_context (element, context,
|
||||
|
@ -456,12 +459,12 @@ gst_nv_base_enc_set_context (GstElement * element, GstContext * context)
|
|||
static gboolean
|
||||
gst_nv_base_enc_sink_query (GstVideoEncoder * enc, GstQuery * query)
|
||||
{
|
||||
#if HAVE_NVENC_GST_GL
|
||||
#if HAVE_NVCODEC_GST_GL
|
||||
GstNvBaseEnc *nvenc = GST_NV_BASE_ENC (enc);
|
||||
#endif
|
||||
|
||||
switch (GST_QUERY_TYPE (query)) {
|
||||
#if HAVE_NVENC_GST_GL
|
||||
#if HAVE_NVCODEC_GST_GL
|
||||
case GST_QUERY_CONTEXT:{
|
||||
gboolean ret;
|
||||
|
||||
|
@ -494,7 +497,7 @@ gst_nv_base_enc_start (GstVideoEncoder * enc)
|
|||
|
||||
nvenc->last_flow = GST_FLOW_OK;
|
||||
|
||||
#if HAVE_NVENC_GST_GL
|
||||
#if HAVE_NVCODEC_GST_GL
|
||||
{
|
||||
gst_gl_ensure_element_data (GST_ELEMENT (nvenc),
|
||||
(GstGLDisplay **) & nvenc->display,
|
||||
|
@ -834,7 +837,7 @@ gst_nv_base_enc_bitstream_thread (gpointer user_data)
|
|||
void *in_buf = state->in_bufs[i];
|
||||
g_assert (in_buf != NULL);
|
||||
|
||||
#if HAVE_NVENC_GST_GL
|
||||
#if HAVE_NVCODEC_GST_GL
|
||||
if (nvenc->gl_input) {
|
||||
struct gl_input_resource *in_gl_resource = in_buf;
|
||||
|
||||
|
@ -972,11 +975,11 @@ gst_nv_base_enc_free_buffers (GstNvBaseEnc * nvenc)
|
|||
for (i = 0; i < nvenc->n_bufs; ++i) {
|
||||
NV_ENC_OUTPUT_PTR out_buf = nvenc->output_bufs[i];
|
||||
|
||||
#if HAVE_NVENC_GST_GL
|
||||
#if HAVE_NVCODEC_GST_GL
|
||||
if (nvenc->gl_input) {
|
||||
struct gl_input_resource *in_gl_resource = nvenc->input_bufs[i];
|
||||
|
||||
cuCtxPushCurrent (nvenc->cuda_ctx);
|
||||
CuCtxPushCurrent (nvenc->cuda_ctx);
|
||||
|
||||
if (in_gl_resource->mapped) {
|
||||
GST_LOG_OBJECT (nvenc, "Unmap resource %p", in_gl_resource);
|
||||
|
@ -998,14 +1001,14 @@ gst_nv_base_enc_free_buffers (GstNvBaseEnc * nvenc)
|
|||
GST_ERROR_OBJECT (nvenc, "Failed to unregister resource %p, ret %d",
|
||||
in_gl_resource, nv_ret);
|
||||
|
||||
nv_ret = cuMemFree ((CUdeviceptr) in_gl_resource->cuda_pointer);
|
||||
nv_ret = CuMemFree ((CUdeviceptr) in_gl_resource->cuda_pointer);
|
||||
if (nv_ret != NV_ENC_SUCCESS) {
|
||||
GST_ERROR_OBJECT (nvenc, "Failed to free CUDA device memory, ret %d",
|
||||
nv_ret);
|
||||
}
|
||||
|
||||
g_free (in_gl_resource);
|
||||
cuCtxPopCurrent (NULL);
|
||||
CuCtxPopCurrent (NULL);
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
|
@ -1282,7 +1285,7 @@ gst_nv_base_enc_set_format (GstVideoEncoder * enc, GstVideoCodecState * state)
|
|||
|
||||
/* now allocate some buffers only on first configuration */
|
||||
if (!old_state) {
|
||||
#if HAVE_NVENC_GST_GL
|
||||
#if HAVE_NVCODEC_GST_GL
|
||||
GstCapsFeatures *features;
|
||||
#endif
|
||||
guint num_macroblocks, i;
|
||||
|
@ -1298,7 +1301,7 @@ gst_nv_base_enc_set_format (GstVideoEncoder * enc, GstVideoCodecState * state)
|
|||
/* input buffers */
|
||||
nvenc->input_bufs = g_new0 (gpointer, nvenc->n_bufs);
|
||||
|
||||
#if HAVE_NVENC_GST_GL
|
||||
#if HAVE_NVCODEC_GST_GL
|
||||
features = gst_caps_get_features (state->caps, 0);
|
||||
if (gst_caps_features_contains (features,
|
||||
GST_CAPS_FEATURE_MEMORY_GL_MEMORY)) {
|
||||
|
@ -1309,7 +1312,7 @@ gst_nv_base_enc_set_format (GstVideoEncoder * enc, GstVideoCodecState * state)
|
|||
pixel_depth += GST_VIDEO_INFO_COMP_DEPTH (info, i);
|
||||
}
|
||||
|
||||
cuCtxPushCurrent (nvenc->cuda_ctx);
|
||||
CuCtxPushCurrent (nvenc->cuda_ctx);
|
||||
for (i = 0; i < nvenc->n_bufs; ++i) {
|
||||
struct gl_input_resource *in_gl_resource =
|
||||
g_new0 (struct gl_input_resource, 1);
|
||||
|
@ -1322,13 +1325,13 @@ gst_nv_base_enc_set_format (GstVideoEncoder * enc, GstVideoCodecState * state)
|
|||
|
||||
/* scratch buffer for non-contigious planer into a contigious buffer */
|
||||
cu_ret =
|
||||
cuMemAllocPitch ((CUdeviceptr *) & in_gl_resource->cuda_pointer,
|
||||
CuMemAllocPitch ((CUdeviceptr *) & in_gl_resource->cuda_pointer,
|
||||
&in_gl_resource->cuda_stride, input_width,
|
||||
_get_frame_data_height (info), 16);
|
||||
if (cu_ret != CUDA_SUCCESS) {
|
||||
const gchar *err;
|
||||
|
||||
cuGetErrorString (cu_ret, &err);
|
||||
CuGetErrorString (cu_ret, &err);
|
||||
GST_ERROR_OBJECT (nvenc, "failed to alocate cuda scratch buffer "
|
||||
"ret %d error :%s", cu_ret, err);
|
||||
g_assert_not_reached ();
|
||||
|
@ -1356,7 +1359,7 @@ gst_nv_base_enc_set_format (GstVideoEncoder * enc, GstVideoCodecState * state)
|
|||
g_async_queue_push (nvenc->in_bufs_pool, nvenc->input_bufs[i]);
|
||||
}
|
||||
|
||||
cuCtxPopCurrent (NULL);
|
||||
CuCtxPopCurrent (NULL);
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
|
@ -1493,7 +1496,7 @@ _plane_get_n_components (GstVideoInfo * info, guint plane)
|
|||
}
|
||||
}
|
||||
|
||||
#if HAVE_NVENC_GST_GL
|
||||
#if HAVE_NVCODEC_GST_GL
|
||||
struct map_gl_input
|
||||
{
|
||||
GstNvBaseEnc *nvenc;
|
||||
|
@ -1505,12 +1508,12 @@ struct map_gl_input
|
|||
static void
|
||||
_map_gl_input_buffer (GstGLContext * context, struct map_gl_input *data)
|
||||
{
|
||||
cudaError_t cuda_ret;
|
||||
CUresult cuda_ret;
|
||||
guint8 *data_pointer;
|
||||
guint i;
|
||||
CUDA_MEMCPY2D param;
|
||||
|
||||
cuCtxPushCurrent (data->nvenc->cuda_ctx);
|
||||
CuCtxPushCurrent (data->nvenc->cuda_ctx);
|
||||
data_pointer = data->in_gl_resource->cuda_pointer;
|
||||
for (i = 0; i < GST_VIDEO_INFO_N_PLANES (data->info); i++) {
|
||||
guint plane_n_components;
|
||||
|
@ -1536,27 +1539,27 @@ _map_gl_input_buffer (GstGLContext * context, struct map_gl_input *data)
|
|||
gl_mem->mem.tex_id);
|
||||
|
||||
cuda_ret =
|
||||
cuGraphicsGLRegisterBuffer (&data->in_gl_resource->cuda_texture,
|
||||
gl_buf_obj->id, cudaGraphicsRegisterFlagsReadOnly);
|
||||
if (cuda_ret != cudaSuccess) {
|
||||
CuGraphicsGLRegisterBuffer (&data->in_gl_resource->cuda_texture,
|
||||
gl_buf_obj->id, CU_GRAPHICS_REGISTER_FLAGS_READ_ONLY);
|
||||
if (cuda_ret != CUDA_SUCCESS) {
|
||||
GST_ERROR_OBJECT (data->nvenc, "failed to register GL texture %u to cuda "
|
||||
"ret :%d", gl_mem->mem.tex_id, cuda_ret);
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
|
||||
cuda_ret =
|
||||
cuGraphicsMapResources (1, &data->in_gl_resource->cuda_texture, 0);
|
||||
if (cuda_ret != cudaSuccess) {
|
||||
CuGraphicsMapResources (1, &data->in_gl_resource->cuda_texture, 0);
|
||||
if (cuda_ret != CUDA_SUCCESS) {
|
||||
GST_ERROR_OBJECT (data->nvenc, "failed to map GL texture %u into cuda "
|
||||
"ret :%d", gl_mem->mem.tex_id, cuda_ret);
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
|
||||
cuda_ret =
|
||||
cuGraphicsResourceGetMappedPointer (&data->in_gl_resource->
|
||||
CuGraphicsResourceGetMappedPointer (&data->in_gl_resource->
|
||||
cuda_plane_pointers[i], &data->in_gl_resource->cuda_num_bytes,
|
||||
data->in_gl_resource->cuda_texture);
|
||||
if (cuda_ret != cudaSuccess) {
|
||||
if (cuda_ret != CUDA_SUCCESS) {
|
||||
GST_ERROR_OBJECT (data->nvenc, "failed to get mapped pointer of map GL "
|
||||
"texture %u in cuda ret :%d", gl_mem->mem.tex_id, cuda_ret);
|
||||
g_assert_not_reached ();
|
||||
|
@ -1580,24 +1583,24 @@ _map_gl_input_buffer (GstGLContext * context, struct map_gl_input *data)
|
|||
param.WidthInBytes = _get_plane_width (data->info, i) * plane_n_components;
|
||||
param.Height = _get_plane_height (data->info, i);
|
||||
|
||||
cuda_ret = cuMemcpy2D (¶m);
|
||||
if (cuda_ret != cudaSuccess) {
|
||||
cuda_ret = CuMemcpy2D (¶m);
|
||||
if (cuda_ret != CUDA_SUCCESS) {
|
||||
GST_ERROR_OBJECT (data->nvenc, "failed to copy GL texture %u into cuda "
|
||||
"ret :%d", gl_mem->mem.tex_id, cuda_ret);
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
|
||||
cuda_ret =
|
||||
cuGraphicsUnmapResources (1, &data->in_gl_resource->cuda_texture, 0);
|
||||
if (cuda_ret != cudaSuccess) {
|
||||
CuGraphicsUnmapResources (1, &data->in_gl_resource->cuda_texture, 0);
|
||||
if (cuda_ret != CUDA_SUCCESS) {
|
||||
GST_ERROR_OBJECT (data->nvenc, "failed to unmap GL texture %u from cuda "
|
||||
"ret :%d", gl_mem->mem.tex_id, cuda_ret);
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
|
||||
cuda_ret =
|
||||
cuGraphicsUnregisterResource (data->in_gl_resource->cuda_texture);
|
||||
if (cuda_ret != cudaSuccess) {
|
||||
CuGraphicsUnregisterResource (data->in_gl_resource->cuda_texture);
|
||||
if (cuda_ret != CUDA_SUCCESS) {
|
||||
GST_ERROR_OBJECT (data->nvenc, "failed to unregister GL texture %u from "
|
||||
"cuda ret :%d", gl_mem->mem.tex_id, cuda_ret);
|
||||
g_assert_not_reached ();
|
||||
|
@ -1608,7 +1611,7 @@ _map_gl_input_buffer (GstGLContext * context, struct map_gl_input *data)
|
|||
data->in_gl_resource->cuda_stride *
|
||||
_get_plane_height (&data->nvenc->input_info, i);
|
||||
}
|
||||
cuCtxPopCurrent (NULL);
|
||||
CuCtxPopCurrent (NULL);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -1712,7 +1715,7 @@ gst_nv_base_enc_handle_frame (GstVideoEncoder * enc, GstVideoCodecFrame * frame)
|
|||
if (!gst_nv_base_enc_set_format (enc, nvenc->input_state))
|
||||
return GST_FLOW_ERROR;
|
||||
}
|
||||
#if HAVE_NVENC_GST_GL
|
||||
#if HAVE_NVCODEC_GST_GL
|
||||
if (nvenc->gl_input)
|
||||
in_map_flags |= GST_MAP_GL;
|
||||
#endif
|
||||
|
@ -1737,7 +1740,7 @@ gst_nv_base_enc_handle_frame (GstVideoEncoder * enc, GstVideoCodecFrame * frame)
|
|||
state = g_new0 (struct frame_state, 1);
|
||||
state->n_buffers = 1;
|
||||
|
||||
#if HAVE_NVENC_GST_GL
|
||||
#if HAVE_NVCODEC_GST_GL
|
||||
if (nvenc->gl_input) {
|
||||
struct gl_input_resource *in_gl_resource = input_buffer;
|
||||
struct map_gl_input data;
|
|
@ -53,8 +53,8 @@ cuda_OK (CUresult result)
|
|||
const gchar *error_name, *error_text;
|
||||
|
||||
if (result != CUDA_SUCCESS) {
|
||||
cuGetErrorName (result, &error_name);
|
||||
cuGetErrorString (result, &error_text);
|
||||
CuGetErrorName (result, &error_name);
|
||||
CuGetErrorString (result, &error_text);
|
||||
GST_WARNING ("CUDA call failed: %s, %s", error_name, error_text);
|
||||
return FALSE;
|
||||
}
|
||||
|
@ -71,7 +71,7 @@ gst_nvdec_cuda_context_finalize (GObject * object)
|
|||
|
||||
if (self->lock) {
|
||||
GST_DEBUG ("destroying CUDA context lock");
|
||||
if (cuda_OK (cuvidCtxLockDestroy (self->lock)))
|
||||
if (cuda_OK (CuvidCtxLockDestroy (self->lock)))
|
||||
self->lock = NULL;
|
||||
else
|
||||
GST_ERROR ("failed to destroy CUDA context lock");
|
||||
|
@ -79,7 +79,7 @@ gst_nvdec_cuda_context_finalize (GObject * object)
|
|||
|
||||
if (self->context) {
|
||||
GST_DEBUG ("destroying CUDA context");
|
||||
if (cuda_OK (cuCtxDestroy (self->context)))
|
||||
if (cuda_OK (CuCtxDestroy (self->context)))
|
||||
self->context = NULL;
|
||||
else
|
||||
GST_ERROR ("failed to destroy CUDA context");
|
||||
|
@ -97,16 +97,16 @@ gst_nvdec_cuda_context_class_init (GstNvDecCudaContextClass * klass)
|
|||
static void
|
||||
gst_nvdec_cuda_context_init (GstNvDecCudaContext * self)
|
||||
{
|
||||
if (!cuda_OK (cuInit (0)))
|
||||
if (!cuda_OK (CuInit (0)))
|
||||
GST_ERROR ("failed to init CUDA");
|
||||
|
||||
if (!cuda_OK (cuCtxCreate (&self->context, CU_CTX_SCHED_AUTO, 0)))
|
||||
if (!cuda_OK (CuCtxCreate (&self->context, CU_CTX_SCHED_AUTO, 0)))
|
||||
GST_ERROR ("failed to create CUDA context");
|
||||
|
||||
if (!cuda_OK (cuCtxPopCurrent (NULL)))
|
||||
if (!cuda_OK (CuCtxPopCurrent (NULL)))
|
||||
GST_ERROR ("failed to pop current CUDA context");
|
||||
|
||||
if (!cuda_OK (cuvidCtxLockCreate (&self->lock, self->context)))
|
||||
if (!cuda_OK (CuvidCtxLockCreate (&self->lock, self->context)))
|
||||
GST_ERROR ("failed to create CUDA context lock");
|
||||
}
|
||||
|
||||
|
@ -126,13 +126,13 @@ register_cuda_resource (GstGLContext * context, gpointer * args)
|
|||
GstMapInfo map_info = GST_MAP_INFO_INIT;
|
||||
guint texture_id;
|
||||
|
||||
if (!cuda_OK (cuvidCtxLock (cgr_info->cuda_context->lock, 0)))
|
||||
if (!cuda_OK (CuvidCtxLock (cgr_info->cuda_context->lock, 0)))
|
||||
GST_WARNING ("failed to lock CUDA context");
|
||||
|
||||
if (gst_memory_map (mem, &map_info, GST_MAP_READ | GST_MAP_GL)) {
|
||||
texture_id = *(guint *) map_info.data;
|
||||
|
||||
if (!cuda_OK (cuGraphicsGLRegisterImage (&cgr_info->resource, texture_id,
|
||||
if (!cuda_OK (CuGraphicsGLRegisterImage (&cgr_info->resource, texture_id,
|
||||
GL_TEXTURE_2D, CU_GRAPHICS_REGISTER_FLAGS_WRITE_DISCARD)))
|
||||
GST_WARNING ("failed to register texture with CUDA");
|
||||
|
||||
|
@ -140,7 +140,7 @@ register_cuda_resource (GstGLContext * context, gpointer * args)
|
|||
} else
|
||||
GST_WARNING ("failed to map memory");
|
||||
|
||||
if (!cuda_OK (cuvidCtxUnlock (cgr_info->cuda_context->lock, 0)))
|
||||
if (!cuda_OK (CuvidCtxUnlock (cgr_info->cuda_context->lock, 0)))
|
||||
GST_WARNING ("failed to unlock CUDA context");
|
||||
}
|
||||
|
||||
|
@ -148,14 +148,14 @@ static void
|
|||
unregister_cuda_resource (GstGLContext * context,
|
||||
GstNvDecCudaGraphicsResourceInfo * cgr_info)
|
||||
{
|
||||
if (!cuda_OK (cuvidCtxLock (cgr_info->cuda_context->lock, 0)))
|
||||
if (!cuda_OK (CuvidCtxLock (cgr_info->cuda_context->lock, 0)))
|
||||
GST_WARNING ("failed to lock CUDA context");
|
||||
|
||||
if (!cuda_OK (cuGraphicsUnregisterResource ((const CUgraphicsResource)
|
||||
if (!cuda_OK (CuGraphicsUnregisterResource ((const CUgraphicsResource)
|
||||
cgr_info->resource)))
|
||||
GST_WARNING ("failed to unregister resource");
|
||||
|
||||
if (!cuda_OK (cuvidCtxUnlock (cgr_info->cuda_context->lock, 0)))
|
||||
if (!cuda_OK (CuvidCtxUnlock (cgr_info->cuda_context->lock, 0)))
|
||||
GST_WARNING ("failed to unlock CUDA context");
|
||||
}
|
||||
|
||||
|
@ -285,14 +285,14 @@ parser_sequence_callback (GstNvDec * nvdec, CUVIDEOFORMAT * format)
|
|||
GST_DEBUG_OBJECT (nvdec, "width: %u, height: %u", width, height);
|
||||
|
||||
if (!nvdec->decoder || (nvdec->width != width || nvdec->height != height)) {
|
||||
if (!cuda_OK (cuvidCtxLock (nvdec->cuda_context->lock, 0))) {
|
||||
if (!cuda_OK (CuvidCtxLock (nvdec->cuda_context->lock, 0))) {
|
||||
GST_ERROR_OBJECT (nvdec, "failed to lock CUDA context");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (nvdec->decoder) {
|
||||
GST_DEBUG_OBJECT (nvdec, "destroying decoder");
|
||||
if (!cuda_OK (cuvidDestroyDecoder (nvdec->decoder))) {
|
||||
if (!cuda_OK (CuvidDestroyDecoder (nvdec->decoder))) {
|
||||
GST_ERROR_OBJECT (nvdec, "failed to destroy decoder");
|
||||
ret = FALSE;
|
||||
} else
|
||||
|
@ -322,12 +322,12 @@ parser_sequence_callback (GstNvDec * nvdec, CUVIDEOFORMAT * format)
|
|||
create_info.target_rect.bottom = height;
|
||||
|
||||
if (nvdec->decoder
|
||||
|| !cuda_OK (cuvidCreateDecoder (&nvdec->decoder, &create_info))) {
|
||||
|| !cuda_OK (CuvidCreateDecoder (&nvdec->decoder, &create_info))) {
|
||||
GST_ERROR_OBJECT (nvdec, "failed to create decoder");
|
||||
ret = FALSE;
|
||||
}
|
||||
|
||||
if (!cuda_OK (cuvidCtxUnlock (nvdec->cuda_context->lock, 0))) {
|
||||
if (!cuda_OK (CuvidCtxUnlock (nvdec->cuda_context->lock, 0))) {
|
||||
GST_ERROR_OBJECT (nvdec, "failed to unlock CUDA context");
|
||||
ret = FALSE;
|
||||
}
|
||||
|
@ -348,13 +348,13 @@ parser_decode_callback (GstNvDec * nvdec, CUVIDPICPARAMS * params)
|
|||
|
||||
GST_LOG_OBJECT (nvdec, "picture index: %u", params->CurrPicIdx);
|
||||
|
||||
if (!cuda_OK (cuvidCtxLock (nvdec->cuda_context->lock, 0)))
|
||||
if (!cuda_OK (CuvidCtxLock (nvdec->cuda_context->lock, 0)))
|
||||
GST_WARNING_OBJECT (nvdec, "failed to lock CUDA context");
|
||||
|
||||
if (!cuda_OK (cuvidDecodePicture (nvdec->decoder, params)))
|
||||
if (!cuda_OK (CuvidDecodePicture (nvdec->decoder, params)))
|
||||
GST_WARNING_OBJECT (nvdec, "failed to decode picture");
|
||||
|
||||
if (!cuda_OK (cuvidCtxUnlock (nvdec->cuda_context->lock, 0)))
|
||||
if (!cuda_OK (CuvidCtxUnlock (nvdec->cuda_context->lock, 0)))
|
||||
GST_WARNING_OBJECT (nvdec, "failed to unlock CUDA context");
|
||||
|
||||
item = g_slice_new (GstNvDecQueueItem);
|
||||
|
@ -404,28 +404,28 @@ maybe_destroy_decoder_and_parser (GstNvDec * nvdec)
|
|||
{
|
||||
gboolean ret = TRUE;
|
||||
|
||||
if (!cuda_OK (cuvidCtxLock (nvdec->cuda_context->lock, 0))) {
|
||||
if (!cuda_OK (CuvidCtxLock (nvdec->cuda_context->lock, 0))) {
|
||||
GST_ERROR_OBJECT (nvdec, "failed to lock CUDA context");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (nvdec->decoder) {
|
||||
GST_DEBUG_OBJECT (nvdec, "destroying decoder");
|
||||
ret = cuda_OK (cuvidDestroyDecoder (nvdec->decoder));
|
||||
ret = cuda_OK (CuvidDestroyDecoder (nvdec->decoder));
|
||||
if (ret)
|
||||
nvdec->decoder = NULL;
|
||||
else
|
||||
GST_ERROR_OBJECT (nvdec, "failed to destroy decoder");
|
||||
}
|
||||
|
||||
if (!cuda_OK (cuvidCtxUnlock (nvdec->cuda_context->lock, 0))) {
|
||||
if (!cuda_OK (CuvidCtxUnlock (nvdec->cuda_context->lock, 0))) {
|
||||
GST_ERROR_OBJECT (nvdec, "failed to unlock CUDA context");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (nvdec->parser) {
|
||||
GST_DEBUG_OBJECT (nvdec, "destroying parser");
|
||||
if (!cuda_OK (cuvidDestroyVideoParser (nvdec->parser))) {
|
||||
if (!cuda_OK (CuvidDestroyVideoParser (nvdec->parser))) {
|
||||
GST_ERROR_OBJECT (nvdec, "failed to destroy parser");
|
||||
return FALSE;
|
||||
}
|
||||
|
@ -556,7 +556,7 @@ gst_nvdec_set_format (GstVideoDecoder * decoder, GstVideoCodecState * state)
|
|||
(PFNVIDDISPLAYCALLBACK) parser_display_callback;
|
||||
|
||||
GST_DEBUG_OBJECT (nvdec, "creating parser");
|
||||
if (!cuda_OK (cuvidCreateVideoParser (&nvdec->parser, &parser_params))) {
|
||||
if (!cuda_OK (CuvidCreateVideoParser (&nvdec->parser, &parser_params))) {
|
||||
GST_ERROR_OBJECT (nvdec, "failed to create parser");
|
||||
return FALSE;
|
||||
}
|
||||
|
@ -572,7 +572,7 @@ copy_video_frame_to_gl_textures (GstGLContext * context, gpointer * args)
|
|||
CUgraphicsResource *resources = (CUgraphicsResource *) args[2];
|
||||
guint num_resources = GPOINTER_TO_UINT (args[3]);
|
||||
CUVIDPROCPARAMS proc_params = { 0, };
|
||||
CUdeviceptr dptr;
|
||||
guintptr dptr;
|
||||
CUarray array;
|
||||
guint pitch, i;
|
||||
CUDA_MEMCPY2D mcpy2d = { 0, };
|
||||
|
@ -583,18 +583,18 @@ copy_video_frame_to_gl_textures (GstGLContext * context, gpointer * args)
|
|||
proc_params.top_field_first = dispinfo->top_field_first;
|
||||
proc_params.unpaired_field = dispinfo->repeat_first_field == -1;
|
||||
|
||||
if (!cuda_OK (cuvidCtxLock (nvdec->cuda_context->lock, 0))) {
|
||||
if (!cuda_OK (CuvidCtxLock (nvdec->cuda_context->lock, 0))) {
|
||||
GST_WARNING_OBJECT (nvdec, "failed to lock CUDA context");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!cuda_OK (cuvidMapVideoFrame (nvdec->decoder, dispinfo->picture_index,
|
||||
if (!cuda_OK (CuvidMapVideoFrame (nvdec->decoder, dispinfo->picture_index,
|
||||
&dptr, &pitch, &proc_params))) {
|
||||
GST_WARNING_OBJECT (nvdec, "failed to map CUDA video frame");
|
||||
goto unlock_cuda_context;
|
||||
}
|
||||
|
||||
if (!cuda_OK (cuGraphicsMapResources (num_resources, resources, NULL))) {
|
||||
if (!cuda_OK (CuGraphicsMapResources (num_resources, resources, NULL))) {
|
||||
GST_WARNING_OBJECT (nvdec, "failed to map CUDA resources");
|
||||
goto unmap_video_frame;
|
||||
}
|
||||
|
@ -606,7 +606,7 @@ copy_video_frame_to_gl_textures (GstGLContext * context, gpointer * args)
|
|||
mcpy2d.WidthInBytes = nvdec->width;
|
||||
|
||||
for (i = 0; i < num_resources; i++) {
|
||||
if (!cuda_OK (cuGraphicsSubResourceGetMappedArray (&array, resources[i], 0,
|
||||
if (!cuda_OK (CuGraphicsSubResourceGetMappedArray (&array, resources[i], 0,
|
||||
0))) {
|
||||
GST_WARNING_OBJECT (nvdec, "failed to map CUDA array");
|
||||
break;
|
||||
|
@ -616,19 +616,19 @@ copy_video_frame_to_gl_textures (GstGLContext * context, gpointer * args)
|
|||
mcpy2d.dstArray = array;
|
||||
mcpy2d.Height = nvdec->height / (i + 1);
|
||||
|
||||
if (!cuda_OK (cuMemcpy2D (&mcpy2d)))
|
||||
if (!cuda_OK (CuMemcpy2D (&mcpy2d)))
|
||||
GST_WARNING_OBJECT (nvdec, "memcpy to mapped array failed");
|
||||
}
|
||||
|
||||
if (!cuda_OK (cuGraphicsUnmapResources (num_resources, resources, NULL)))
|
||||
if (!cuda_OK (CuGraphicsUnmapResources (num_resources, resources, NULL)))
|
||||
GST_WARNING_OBJECT (nvdec, "failed to unmap CUDA resources");
|
||||
|
||||
unmap_video_frame:
|
||||
if (!cuda_OK (cuvidUnmapVideoFrame (nvdec->decoder, dptr)))
|
||||
if (!cuda_OK (CuvidUnmapVideoFrame (nvdec->decoder, dptr)))
|
||||
GST_WARNING_OBJECT (nvdec, "failed to unmap CUDA video frame");
|
||||
|
||||
unlock_cuda_context:
|
||||
if (!cuda_OK (cuvidCtxUnlock (nvdec->cuda_context->lock, 0)))
|
||||
if (!cuda_OK (CuvidCtxUnlock (nvdec->cuda_context->lock, 0)))
|
||||
GST_WARNING_OBJECT (nvdec, "failed to unlock CUDA context");
|
||||
}
|
||||
|
||||
|
@ -963,7 +963,7 @@ gst_nvdec_handle_frame (GstVideoDecoder * decoder, GstVideoCodecFrame * frame)
|
|||
if (GST_BUFFER_IS_DISCONT (frame->input_buffer))
|
||||
packet.flags |= CUVID_PKT_DISCONTINUITY;
|
||||
|
||||
if (!cuda_OK (cuvidParseVideoData (nvdec->parser, &packet)))
|
||||
if (!cuda_OK (CuvidParseVideoData (nvdec->parser, &packet)))
|
||||
GST_WARNING_OBJECT (nvdec, "parser failed");
|
||||
|
||||
gst_buffer_unmap (frame->input_buffer, &map_info);
|
||||
|
@ -984,7 +984,7 @@ gst_nvdec_flush (GstVideoDecoder * decoder)
|
|||
packet.payload = NULL;
|
||||
packet.flags = CUVID_PKT_ENDOFSTREAM;
|
||||
|
||||
if (!cuda_OK (cuvidParseVideoData (nvdec->parser, &packet)))
|
||||
if (!cuda_OK (CuvidParseVideoData (nvdec->parser, &packet)))
|
||||
GST_WARNING_OBJECT (nvdec, "parser failed");
|
||||
|
||||
handle_pending_frames (nvdec);
|
||||
|
@ -1004,7 +1004,7 @@ gst_nvdec_drain (GstVideoDecoder * decoder)
|
|||
packet.payload = NULL;
|
||||
packet.flags = CUVID_PKT_ENDOFSTREAM;
|
||||
|
||||
if (!cuda_OK (cuvidParseVideoData (nvdec->parser, &packet)))
|
||||
if (!cuda_OK (CuvidParseVideoData (nvdec->parser, &packet)))
|
||||
GST_WARNING_OBJECT (nvdec, "parser failed");
|
||||
|
||||
return handle_pending_frames (nvdec);
|
|
@ -30,7 +30,8 @@
|
|||
|
||||
#include <gst/gl/gl.h>
|
||||
#include <gst/gl/gstglfuncs.h>
|
||||
#include "nvcuvid.h"
|
||||
#include "gstcuvidloader.h"
|
||||
#include "gstcudaloader.h"
|
||||
#include <cudaGL.h>
|
||||
|
||||
G_BEGIN_DECLS
|
|
@ -283,7 +283,7 @@ gst_nvenc_create_cuda_context (guint device_id)
|
|||
|
||||
GST_INFO ("Initialising CUDA..");
|
||||
|
||||
cres = cuInit (0);
|
||||
cres = CuInit (0);
|
||||
|
||||
if (cres != CUDA_SUCCESS) {
|
||||
GST_WARNING ("Failed to initialise CUDA, error code: 0x%08x", cres);
|
||||
|
@ -292,7 +292,7 @@ gst_nvenc_create_cuda_context (guint device_id)
|
|||
|
||||
GST_INFO ("Initialised CUDA");
|
||||
|
||||
cres = cuDeviceGetCount (&dev_count);
|
||||
cres = CuDeviceGetCount (&dev_count);
|
||||
if (cres != CUDA_SUCCESS || dev_count == 0) {
|
||||
GST_WARNING ("No CUDA devices detected");
|
||||
return NULL;
|
||||
|
@ -300,11 +300,11 @@ gst_nvenc_create_cuda_context (guint device_id)
|
|||
|
||||
GST_INFO ("%d CUDA device(s) detected", dev_count);
|
||||
for (i = 0; i < dev_count; ++i) {
|
||||
if (cuDeviceGet (&cdev, i) == CUDA_SUCCESS
|
||||
&& cuDeviceGetName (name, sizeof (name), cdev) == CUDA_SUCCESS
|
||||
&& cuDeviceGetAttribute (&maj,
|
||||
if (CuDeviceGet (&cdev, i) == CUDA_SUCCESS
|
||||
&& CuDeviceGetName (name, sizeof (name), cdev) == CUDA_SUCCESS
|
||||
&& CuDeviceGetAttribute (&maj,
|
||||
CU_DEVICE_ATTRIBUTE_COMPUTE_CAPABILITY_MAJOR, cdev) == CUDA_SUCCESS
|
||||
&& cuDeviceGetAttribute (&min,
|
||||
&& CuDeviceGetAttribute (&min,
|
||||
CU_DEVICE_ATTRIBUTE_COMPUTE_CAPABILITY_MINOR,
|
||||
cdev) == CUDA_SUCCESS) {
|
||||
GST_INFO ("GPU #%d supports NVENC: %s (%s) (Compute SM %d.%d)", i,
|
||||
|
@ -321,12 +321,12 @@ gst_nvenc_create_cuda_context (guint device_id)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
if (cuCtxCreate (&cuda_ctx, 0, cuda_dev) != CUDA_SUCCESS) {
|
||||
if (CuCtxCreate (&cuda_ctx, 0, cuda_dev) != CUDA_SUCCESS) {
|
||||
GST_WARNING ("Failed to create CUDA context for cuda device %d", cuda_dev);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (cuCtxPopCurrent (&old_ctx) != CUDA_SUCCESS) {
|
||||
if (CuCtxPopCurrent (&old_ctx) != CUDA_SUCCESS) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -339,7 +339,7 @@ gboolean
|
|||
gst_nvenc_destroy_cuda_context (CUcontext ctx)
|
||||
{
|
||||
GST_INFO ("Destroying CUDA context %p", ctx);
|
||||
return (cuCtxDestroy (ctx) == CUDA_SUCCESS);
|
||||
return (CuCtxDestroy (ctx) == CUDA_SUCCESS);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
|
@ -362,31 +362,27 @@ load_nvenc_library (void)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
plugin_init (GstPlugin * plugin)
|
||||
gboolean
|
||||
gst_nvenc_plugin_init (GstPlugin * plugin)
|
||||
{
|
||||
gboolean ret = TRUE;
|
||||
|
||||
GST_DEBUG_CATEGORY_INIT (gst_nvenc_debug, "nvenc", 0, "Nvidia NVENC encoder");
|
||||
|
||||
nvenc_api.version = NV_ENCODE_API_FUNCTION_LIST_VER;
|
||||
if (!load_nvenc_library ())
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
|
||||
if (nvEncodeAPICreateInstance (&nvenc_api) != NV_ENC_SUCCESS) {
|
||||
GST_ERROR ("Failed to get NVEncodeAPI function table!");
|
||||
} else {
|
||||
GST_INFO ("Created NVEncodeAPI instance, got function table");
|
||||
|
||||
gst_element_register (plugin, "nvh264enc", GST_RANK_PRIMARY * 2,
|
||||
ret &= gst_element_register (plugin, "nvh264enc", GST_RANK_PRIMARY * 2,
|
||||
gst_nv_h264_enc_get_type ());
|
||||
gst_element_register (plugin, "nvh265enc", GST_RANK_PRIMARY * 2,
|
||||
ret &= gst_element_register (plugin, "nvh265enc", GST_RANK_PRIMARY * 2,
|
||||
gst_nv_h265_enc_get_type ());
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
return ret;
|
||||
}
|
||||
|
||||
GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
|
||||
GST_VERSION_MINOR,
|
||||
nvenc,
|
||||
"GStreamer NVENC plugin",
|
||||
plugin_init, VERSION, "LGPL", GST_PACKAGE_NAME, GST_PACKAGE_ORIGIN)
|
|
@ -23,8 +23,8 @@
|
|||
#include <gst/gst.h>
|
||||
#include <gst/video/video.h>
|
||||
|
||||
#include "gstcudaloader.h"
|
||||
#include "nvEncodeAPI.h"
|
||||
#include <cuda.h>
|
||||
|
||||
GST_DEBUG_CATEGORY_EXTERN (gst_nvenc_debug);
|
||||
|
||||
|
@ -36,4 +36,7 @@ gboolean gst_nvenc_cmp_guid (GUID g1, GUID g2);
|
|||
|
||||
NV_ENC_BUFFER_FORMAT gst_nvenc_get_nv_buffer_format (GstVideoFormat fmt);
|
||||
|
||||
gboolean gst_nvenc_plugin_init (GstPlugin * plugin);
|
||||
|
||||
|
||||
#endif /* __GST_NVENC_H_INCLUDED__ */
|
|
@ -30,17 +30,10 @@
|
|||
GST_DEBUG_CATEGORY_STATIC (gst_nv_h264_enc_debug);
|
||||
#define GST_CAT_DEFAULT gst_nv_h264_enc_debug
|
||||
|
||||
#if HAVE_NVENC_GST_GL
|
||||
#include <cuda.h>
|
||||
#include <cuda_runtime_api.h>
|
||||
#include <cuda_gl_interop.h>
|
||||
#include <gst/gl/gl.h>
|
||||
#endif
|
||||
|
||||
#define parent_class gst_nv_h264_enc_parent_class
|
||||
G_DEFINE_TYPE (GstNvH264Enc, gst_nv_h264_enc, GST_TYPE_NV_BASE_ENC);
|
||||
|
||||
#if HAVE_NVENC_GST_GL
|
||||
#if HAVE_NVCODEC_GST_GL
|
||||
#define GL_CAPS_STR \
|
||||
";" \
|
||||
"video/x-raw(memory:GLMemory), " \
|
|
@ -31,17 +31,10 @@
|
|||
GST_DEBUG_CATEGORY_STATIC (gst_nv_h265_enc_debug);
|
||||
#define GST_CAT_DEFAULT gst_nv_h265_enc_debug
|
||||
|
||||
#if HAVE_NVENC_GST_GL
|
||||
#include <cuda.h>
|
||||
#include <cuda_runtime_api.h>
|
||||
#include <cuda_gl_interop.h>
|
||||
#include <gst/gl/gl.h>
|
||||
#endif
|
||||
|
||||
#define parent_class gst_nv_h265_enc_parent_class
|
||||
G_DEFINE_TYPE (GstNvH265Enc, gst_nv_h265_enc, GST_TYPE_NV_BASE_ENC);
|
||||
|
||||
#if HAVE_NVENC_GST_GL
|
||||
#if HAVE_NVCODEC_GST_GL
|
||||
#define GL_CAPS_STR \
|
||||
";" \
|
||||
"video/x-raw(memory:GLMemory), " \
|
102
sys/nvcodec/meson.build
Normal file
102
sys/nvcodec/meson.build
Normal file
|
@ -0,0 +1,102 @@
|
|||
nvcodec_sources = [
|
||||
'plugin.c',
|
||||
'gstnvenc.c',
|
||||
'gstnvbaseenc.c',
|
||||
'gstnvh264enc.c',
|
||||
'gstnvh265enc.c',
|
||||
'gstcudaloader.c',
|
||||
]
|
||||
|
||||
nvdec_sources = [
|
||||
'gstnvdec.c',
|
||||
'gstcuvidloader.c',
|
||||
]
|
||||
|
||||
use_nvcodec_gl = false
|
||||
extra_c_args = []
|
||||
|
||||
cuda_dep = dependency('', required : false)
|
||||
cuda_header_dep = dependency('', required : false)
|
||||
cuda_incdir = ''
|
||||
|
||||
nvcodec_option = get_option('nvcodec')
|
||||
if nvcodec_option.disabled()
|
||||
subdir_done()
|
||||
endif
|
||||
|
||||
cuda_versions = [
|
||||
'10.1',
|
||||
'10.0',
|
||||
'9.2',
|
||||
'9.1',
|
||||
'9.0',
|
||||
'8.0',
|
||||
'7.5',
|
||||
'7.0',
|
||||
'6.5',
|
||||
]
|
||||
cuda_ver = ''
|
||||
|
||||
# FIXME: use break syntax when we use meson >= '0.49'
|
||||
foreach v : cuda_versions
|
||||
if cuda_ver == ''
|
||||
cuda_dep = dependency('cuda-' + v, required: false)
|
||||
if cuda_dep.found()
|
||||
cuda_ver = v
|
||||
endif
|
||||
endif
|
||||
endforeach
|
||||
|
||||
if cuda_dep.found()
|
||||
if cc.has_header('cuda.h', dependencies: cuda_dep)
|
||||
cuda_header_dep = cuda_dep.partial_dependency(compile_args : true, includes : true)
|
||||
endif
|
||||
endif
|
||||
|
||||
if not cuda_header_dep.found()
|
||||
cuda_root = run_command(python3, '-c', 'import os; print(os.environ.get("CUDA_PATH"))').stdout().strip()
|
||||
if cuda_root != '' and cuda_root != 'None'
|
||||
cuda_incdir = join_paths (cuda_root, 'include')
|
||||
|
||||
if cc.has_header('cuda.h', args: '-I' + cuda_incdir)
|
||||
cuda_header_dep = declare_dependency(include_directories: include_directories(cuda_incdir))
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
if not cuda_header_dep.found()
|
||||
if nvcodec_option.enabled()
|
||||
error('The nvcodec plugin was enabled explicitly, but required CUDA dependency was not found.')
|
||||
endif
|
||||
subdir_done()
|
||||
endif
|
||||
|
||||
if gstgl_dep.found()
|
||||
if cuda_dep.found()
|
||||
if cc.has_header('cudaGL.h', dependencies: cuda_dep)
|
||||
use_nvcodec_gl = true
|
||||
endif
|
||||
else
|
||||
if cc.has_header('cudaGL.h', args: '-I' + cuda_incdir)
|
||||
use_nvcodec_gl = true
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
if use_nvcodec_gl
|
||||
# FIXME: make nvdec usable without OpenGL dependency
|
||||
nvcodec_sources += nvdec_sources
|
||||
extra_c_args += ['-DHAVE_NVCODEC_GST_GL=1']
|
||||
endif
|
||||
|
||||
gstnvcodec = library('gstnvcodec',
|
||||
nvcodec_sources,
|
||||
c_args : gst_plugins_bad_args + extra_c_args,
|
||||
include_directories : [configinc],
|
||||
dependencies : [gstbase_dep, gstvideo_dep, gstpbutils_dep, gstgl_dep, cuda_header_dep, gmodule_dep],
|
||||
install : true,
|
||||
install_dir : plugins_install_dir,
|
||||
)
|
||||
pkgconfig.generate(gstnvcodec, install_dir : plugins_pkgconfig_install_dir)
|
||||
plugins += [gstnvcodec]
|
||||
|
|
@ -29,15 +29,33 @@
|
|||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#if HAVE_NVCODEC_GST_GL
|
||||
#include "gstnvdec.h"
|
||||
#endif
|
||||
|
||||
#include "gstnvenc.h"
|
||||
|
||||
static gboolean
|
||||
plugin_init (GstPlugin * plugin)
|
||||
{
|
||||
return gst_element_register (plugin, "nvdec", GST_RANK_PRIMARY,
|
||||
GST_TYPE_NVDEC);
|
||||
gboolean ret = TRUE;
|
||||
|
||||
if (!gst_cuda_load_library ())
|
||||
return TRUE;
|
||||
|
||||
#if HAVE_NVCODEC_GST_GL
|
||||
/* FIXME: make nvdec usable without OpenGL dependency */
|
||||
if (gst_cuvid_load_library ()) {
|
||||
ret &= gst_element_register (plugin, "nvdec", GST_RANK_PRIMARY,
|
||||
GST_TYPE_NVDEC);
|
||||
}
|
||||
#endif
|
||||
|
||||
ret &= gst_nvenc_plugin_init (plugin);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
GST_PLUGIN_DEFINE (GST_VERSION_MAJOR, GST_VERSION_MINOR, nvdec,
|
||||
"GStreamer NVDEC plugin", plugin_init, VERSION, "BSD",
|
||||
GST_PLUGIN_DEFINE (GST_VERSION_MAJOR, GST_VERSION_MINOR, nvcodec,
|
||||
"GStreamer NVCODEC plugin", plugin_init, VERSION, "LGPL",
|
||||
GST_PACKAGE_NAME, GST_PACKAGE_ORIGIN)
|
|
@ -1,28 +0,0 @@
|
|||
plugin_LTLIBRARIES = libgstnvdec.la
|
||||
|
||||
libgstnvdec_la_SOURCES = \
|
||||
gstnvdec.c \
|
||||
plugin.c
|
||||
|
||||
noinst_HEADERS = \
|
||||
cuviddec.h \
|
||||
gstnvdec.h \
|
||||
nvcuvid.h
|
||||
|
||||
libgstnvdec_la_CFLAGS = \
|
||||
$(GST_PLUGINS_BAD_CFLAGS) \
|
||||
$(GST_GL_CFLAGS) \
|
||||
$(GST_PBUTILS_CFLAGS) \
|
||||
$(GST_VIDEO_CFLAGS) \
|
||||
$(GST_CFLAGS) \
|
||||
$(CUDA_CFLAGS)
|
||||
|
||||
libgstnvdec_la_LIBADD = \
|
||||
$(GST_GL_LIBS) \
|
||||
$(GST_PBUTILS_LIBS) \
|
||||
$(GST_VIDEO_LIBS) \
|
||||
$(GST_LIBS)
|
||||
|
||||
libgstnvdec_la_LIBADD += $(CUDA_LIBS) -lnvcuvid
|
||||
|
||||
libgstnvdec_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
|
|
@ -1,51 +0,0 @@
|
|||
nvdec_sources = [
|
||||
'gstnvdec.c',
|
||||
'plugin.c'
|
||||
]
|
||||
|
||||
nvcuvid_dep_found = false
|
||||
nvcuvid_incdirs = []
|
||||
|
||||
nvdec_option = get_option('nvdec')
|
||||
if nvdec_option.disabled()
|
||||
subdir_done()
|
||||
endif
|
||||
|
||||
if host_machine.system() == 'windows'
|
||||
cuda_libdirs = [cuda_libdir]
|
||||
# NOTE: Newer CUDA toolkit versions do not ship with the nvcuvid library, and
|
||||
# you must get it from the Nvidia Video Codec SDK. The SDK ships as a zip
|
||||
# file, so there's no installer and you have to set this env var yourself.
|
||||
video_sdk_root = run_command(python3, '-c', 'import os; print(os.environ.get("NVIDIA_VIDEO_CODEC_SDK_PATH"))').stdout().strip()
|
||||
if video_sdk_root != '' and video_sdk_root != 'None'
|
||||
cuda_libdirs += [join_paths(video_sdk_root, 'Samples', 'NvCodec', 'Lib', arc)]
|
||||
nvcuvid_incdirs = include_directories(join_paths(video_sdk_root, 'Samples', 'NvCodec', 'NvDecoder'))
|
||||
endif
|
||||
nvcuvid_lib = cc.find_library('nvcuvid', dirs: cuda_libdirs, required: nvdec_option)
|
||||
else
|
||||
nvcuvid_lib = cc.find_library('nvcuvid', required: nvdec_option)
|
||||
endif
|
||||
|
||||
if nvcuvid_lib.found() and cc.has_function('cuvidCtxLock', dependencies: nvcuvid_lib)
|
||||
nvcuvid_dep = declare_dependency(dependencies: nvcuvid_lib,
|
||||
include_directories: nvcuvid_incdirs)
|
||||
nvcuvid_dep_found = true
|
||||
endif
|
||||
|
||||
if nvdec_option.enabled() and not nvcuvid_dep_found
|
||||
error('The nvdec plugin was enabled explicitly, but required nvcuvid library was not found.')
|
||||
endif
|
||||
|
||||
if nvcuvid_dep_found
|
||||
gstnvdec = library('gstnvdec',
|
||||
nvdec_sources,
|
||||
c_args : gst_plugins_bad_args,
|
||||
include_directories : [configinc],
|
||||
dependencies : [gstbase_dep, gstvideo_dep, gstpbutils_dep, gstgl_dep, cuda_dep, cudart_dep, nvcuvid_dep],
|
||||
install : true,
|
||||
install_dir : plugins_install_dir,
|
||||
)
|
||||
pkgconfig.generate(gstnvdec, install_dir : plugins_pkgconfig_install_dir)
|
||||
plugins += [gstnvdec]
|
||||
endif
|
||||
|
|
@ -1,34 +0,0 @@
|
|||
plugin_LTLIBRARIES = libgstnvenc.la
|
||||
|
||||
libgstnvenc_la_SOURCES = \
|
||||
gstnvenc.c \
|
||||
gstnvbaseenc.c \
|
||||
gstnvh264enc.c \
|
||||
gstnvh265enc.c
|
||||
|
||||
noinst_HEADERS = \
|
||||
gstnvenc.h \
|
||||
gstnvbaseenc.h \
|
||||
gstnvh264enc.h \
|
||||
gstnvh265enc.h \
|
||||
nvEncodeAPI.h
|
||||
|
||||
libgstnvenc_la_CFLAGS = \
|
||||
$(GST_PLUGINS_BAD_CFLAGS) \
|
||||
$(GST_PBUTILS_CFLAGS) \
|
||||
$(GST_VIDEO_CFLAGS) \
|
||||
$(GST_CFLAGS) \
|
||||
$(CUDA_CFLAGS)
|
||||
|
||||
libgstnvenc_la_LIBADD = \
|
||||
$(GST_PBUTILS_LIBS) \
|
||||
$(GST_VIDEO_LIBS) \
|
||||
$(GST_LIBS) \
|
||||
$(CUDA_LIBS) \
|
||||
$(GMODULE_NO_EXPORT_LIBS)
|
||||
|
||||
if USE_NVENC_GST_GL
|
||||
libgstnvenc_la_CFLAGS += $(GST_GL_CFLAGS)
|
||||
libgstnvenc_la_LIBADD += $(GST_GL_LIBS)
|
||||
endif
|
||||
libgstnvenc_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
|
|
@ -1,30 +0,0 @@
|
|||
This plugin is intended for use with NVIDIA hardware. Specifically, the NVENC
|
||||
block available in recent NVIDIA GPU hardware. This is provided by a
|
||||
libnvidia-encode library provided by NVIDIA graphic drivers.
|
||||
|
||||
Requirements
|
||||
------------
|
||||
Cuda > 6.5
|
||||
NVENC 5.0
|
||||
|
||||
See https://developer.nvidia.com/nvidia-video-codec-sdk for a list of
|
||||
supported GPU's.
|
||||
|
||||
Building
|
||||
--------
|
||||
1. Retrieve the NVENC SDK
|
||||
from https://developer.nvidia.com/nvidia-video-codec-sdk
|
||||
- http://developer.download.nvidia.com/compute/nvenc/v5.0/nvenc_5.0.1_sdk.zip
|
||||
2. unzip this somewhere and retreive or note the location of the
|
||||
nvEncodeAPI.h under nvenc_api-5.0.1/Samples/common/inc/
|
||||
3. Retreive a version of cuda from
|
||||
https://developer.nvidia.com/cuda-downloads and install somewhere noting
|
||||
the installation prefix (typically /opt/cuda or /usr/local/cuda)
|
||||
4. Now that the dependencies are sorted, there are a couple of
|
||||
environment variables and/or or configure arguments that are needed to
|
||||
detect the necessary libraries/headers.
|
||||
|
||||
More information is available from the following locations
|
||||
|
||||
[1] - https://developer.nvidia.com/cuda-downloads
|
||||
[2] - https://developer.nvidia.com/nvidia-video-codec-sdk
|
|
@ -1,11 +0,0 @@
|
|||
- check supported encoding formats (H.264 etc.), don't assume H.264
|
||||
|
||||
- check performance (time taken) of first cuInit()
|
||||
|
||||
- provide buffer pool
|
||||
|
||||
- more formats
|
||||
|
||||
- renegotiation
|
||||
|
||||
- support outputting of AVC as well as byte-stream, negotiate automatically
|
|
@ -1,41 +0,0 @@
|
|||
nvenc_sources = [
|
||||
'gstnvbaseenc.c',
|
||||
'gstnvenc.c',
|
||||
'gstnvh264enc.c',
|
||||
'gstnvh265enc.c',
|
||||
]
|
||||
|
||||
use_nvenc_gl = false
|
||||
extra_c_args = []
|
||||
|
||||
nvenc_option = get_option('nvenc')
|
||||
if nvenc_option.disabled()
|
||||
subdir_done()
|
||||
endif
|
||||
|
||||
if cuda_dep.type_name() == 'internal'
|
||||
if cc.has_header('cuda_gl_interop.h', args: '-I' + cuda_incdir)
|
||||
use_nvenc_gl = true
|
||||
endif
|
||||
else
|
||||
if cc.has_header('cuda_gl_interop.h', dependencies: cuda_dep)
|
||||
use_nvenc_gl = true
|
||||
endif
|
||||
endif
|
||||
|
||||
if use_nvenc_gl
|
||||
nvenc_gl_dep = gstgl_dep
|
||||
extra_c_args += ['-DHAVE_NVENC_GST_GL=1']
|
||||
endif
|
||||
|
||||
gstnvenc = library('gstnvenc',
|
||||
nvenc_sources,
|
||||
c_args : gst_plugins_bad_args + extra_c_args,
|
||||
include_directories : [configinc],
|
||||
dependencies : [gstbase_dep, gstvideo_dep, gstpbutils_dep, nvenc_gl_dep, cuda_dep, cudart_dep, gmodule_dep],
|
||||
install : true,
|
||||
install_dir : plugins_install_dir,
|
||||
)
|
||||
pkgconfig.generate(gstnvenc, install_dir : plugins_pkgconfig_install_dir)
|
||||
plugins += [gstnvenc]
|
||||
|
|
@ -234,7 +234,7 @@ else
|
|||
check_msdk=
|
||||
endif
|
||||
|
||||
if USE_NVENC
|
||||
if USE_NVCODEC
|
||||
check_nvenc=elements/nvenc
|
||||
else
|
||||
check_nvenc=
|
||||
|
|
|
@ -14,15 +14,6 @@ exif_dep = dependency('libexif', version : '>= 0.6.16', required : false)
|
|||
|
||||
enable_gst_player_tests = get_option('gst_player_tests')
|
||||
|
||||
# Need explicit dependency listing for nvenc on Windows
|
||||
nvenc_test_deps = []
|
||||
if cuda_dep.found() and cudart_dep.found()
|
||||
nvenc_test_deps += [cuda_dep, cudart_dep, gmodule_dep, gstgl_dep]
|
||||
if use_nvenc_gl
|
||||
nvenc_test_deps += gstgl_dep
|
||||
endif
|
||||
endif
|
||||
|
||||
# name, condition when to skip the test and extra dependencies
|
||||
base_tests = [
|
||||
[['elements/aiffparse.c']],
|
||||
|
@ -43,7 +34,7 @@ base_tests = [
|
|||
[['elements/msdkh264enc.c'], not have_msdk, [msdk_dep]],
|
||||
[['elements/mxfdemux.c']],
|
||||
[['elements/mxfmux.c']],
|
||||
[['elements/nvenc.c'], not cuda_dep.found() or not cudart_dep.found(), nvenc_test_deps],
|
||||
[['elements/nvenc.c'], not cuda_header_dep.found(), [gmodule_dep, gstgl_dep]],
|
||||
[['elements/pcapparse.c'], false, [libparser_dep]],
|
||||
[['elements/pnm.c']],
|
||||
[['elements/rtponvifparse.c']],
|
||||
|
|
Loading…
Reference in a new issue