diff --git a/configure.ac b/configure.ac index 3aaadbd090..9968f9229c 100644 --- a/configure.ac +++ b/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 + #else + #include + #endif + #include ]) 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 diff --git a/meson_options.txt b/meson_options.txt index d6db86f3a3..607e1e27f4 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -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') diff --git a/sys/Makefile.am b/sys/Makefile.am index 8365bd2947..e111595f39 100644 --- a/sys/Makefile.am +++ b/sys/Makefile.am @@ -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 diff --git a/sys/meson.build b/sys/meson.build index 0b69ad069a..96cb08cd84 100644 --- a/sys/meson.build +++ b/sys/meson.build @@ -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 diff --git a/sys/nvcodec/Makefile.am b/sys/nvcodec/Makefile.am new file mode 100644 index 0000000000..d81f79a899 --- /dev/null +++ b/sys/nvcodec/Makefile.am @@ -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) diff --git a/sys/nvdec/cuviddec.h b/sys/nvcodec/cuviddec.h similarity index 100% rename from sys/nvdec/cuviddec.h rename to sys/nvcodec/cuviddec.h diff --git a/sys/nvcodec/gstcudaloader.c b/sys/nvcodec/gstcudaloader.c new file mode 100644 index 0000000000..ff6d6e76bf --- /dev/null +++ b/sys/nvcodec/gstcudaloader.c @@ -0,0 +1,331 @@ +/* GStreamer + * Copyright (C) 2019 Seungha Yang + * + * 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 + +#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); +} diff --git a/sys/nvcodec/gstcudaloader.h b/sys/nvcodec/gstcudaloader.h new file mode 100644 index 0000000000..147b43ac80 --- /dev/null +++ b/sys/nvcodec/gstcudaloader.h @@ -0,0 +1,128 @@ +/* GStreamer + * Copyright (C) 2019 Seungha Yang + * + * 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 +#include + +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__ */ diff --git a/sys/nvcodec/gstcuvidloader.c b/sys/nvcodec/gstcuvidloader.c new file mode 100644 index 0000000000..9943acb3e8 --- /dev/null +++ b/sys/nvcodec/gstcuvidloader.c @@ -0,0 +1,203 @@ +/* GStreamer + * Copyright (C) 2019 Seungha Yang + * + * 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 + +#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); +} diff --git a/sys/nvcodec/gstcuvidloader.h b/sys/nvcodec/gstcuvidloader.h new file mode 100644 index 0000000000..51d252a885 --- /dev/null +++ b/sys/nvcodec/gstcuvidloader.h @@ -0,0 +1,80 @@ +/* GStreamer + * Copyright (C) 2019 Seungha Yang + * + * 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 +#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__ */ diff --git a/sys/nvenc/gstnvbaseenc.c b/sys/nvcodec/gstnvbaseenc.c similarity index 97% rename from sys/nvenc/gstnvbaseenc.c rename to sys/nvcodec/gstnvbaseenc.c index 9160755422..fe2cfc7770 100644 --- a/sys/nvenc/gstnvbaseenc.c +++ b/sys/nvcodec/gstnvbaseenc.c @@ -29,12 +29,15 @@ #define GST_CAT_DEFAULT gst_nvenc_debug -#if HAVE_NVENC_GST_GL -#include -#include -#include -#include +#if HAVE_NVCODEC_GST_GL #include +/* missing headers in old cudaGL.h */ +#ifdef __APPLE__ +#include +#else +#include +#endif +#include #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; diff --git a/sys/nvenc/gstnvbaseenc.h b/sys/nvcodec/gstnvbaseenc.h similarity index 100% rename from sys/nvenc/gstnvbaseenc.h rename to sys/nvcodec/gstnvbaseenc.h diff --git a/sys/nvdec/gstnvdec.c b/sys/nvcodec/gstnvdec.c similarity index 94% rename from sys/nvdec/gstnvdec.c rename to sys/nvcodec/gstnvdec.c index 2bc44d24e3..0586fc256f 100644 --- a/sys/nvdec/gstnvdec.c +++ b/sys/nvcodec/gstnvdec.c @@ -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); diff --git a/sys/nvdec/gstnvdec.h b/sys/nvcodec/gstnvdec.h similarity index 98% rename from sys/nvdec/gstnvdec.h rename to sys/nvcodec/gstnvdec.h index a643b1bf4a..e8ee1f3923 100644 --- a/sys/nvdec/gstnvdec.h +++ b/sys/nvcodec/gstnvdec.h @@ -30,7 +30,8 @@ #include #include -#include "nvcuvid.h" +#include "gstcuvidloader.h" +#include "gstcudaloader.h" #include G_BEGIN_DECLS diff --git a/sys/nvenc/gstnvenc.c b/sys/nvcodec/gstnvenc.c similarity index 92% rename from sys/nvenc/gstnvenc.c rename to sys/nvcodec/gstnvenc.c index 8fa83fc923..6a4f38d528 100644 --- a/sys/nvenc/gstnvenc.c +++ b/sys/nvcodec/gstnvenc.c @@ -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) diff --git a/sys/nvenc/gstnvenc.h b/sys/nvcodec/gstnvenc.h similarity index 93% rename from sys/nvenc/gstnvenc.h rename to sys/nvcodec/gstnvenc.h index 2af23ed1e8..71b4384ce4 100644 --- a/sys/nvenc/gstnvenc.h +++ b/sys/nvcodec/gstnvenc.h @@ -23,8 +23,8 @@ #include #include +#include "gstcudaloader.h" #include "nvEncodeAPI.h" -#include 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__ */ diff --git a/sys/nvenc/gstnvh264enc.c b/sys/nvcodec/gstnvh264enc.c similarity index 99% rename from sys/nvenc/gstnvh264enc.c rename to sys/nvcodec/gstnvh264enc.c index c38e032234..ed3508aa95 100644 --- a/sys/nvenc/gstnvh264enc.c +++ b/sys/nvcodec/gstnvh264enc.c @@ -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 -#include -#include -#include -#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), " \ diff --git a/sys/nvenc/gstnvh264enc.h b/sys/nvcodec/gstnvh264enc.h similarity index 100% rename from sys/nvenc/gstnvh264enc.h rename to sys/nvcodec/gstnvh264enc.h diff --git a/sys/nvenc/gstnvh265enc.c b/sys/nvcodec/gstnvh265enc.c similarity index 98% rename from sys/nvenc/gstnvh265enc.c rename to sys/nvcodec/gstnvh265enc.c index 74ec02cc09..1b1138fcfe 100644 --- a/sys/nvenc/gstnvh265enc.c +++ b/sys/nvcodec/gstnvh265enc.c @@ -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 -#include -#include -#include -#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), " \ diff --git a/sys/nvenc/gstnvh265enc.h b/sys/nvcodec/gstnvh265enc.h similarity index 100% rename from sys/nvenc/gstnvh265enc.h rename to sys/nvcodec/gstnvh265enc.h diff --git a/sys/nvcodec/meson.build b/sys/nvcodec/meson.build new file mode 100644 index 0000000000..7c1ec3a89c --- /dev/null +++ b/sys/nvcodec/meson.build @@ -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] + diff --git a/sys/nvenc/nvEncodeAPI.h b/sys/nvcodec/nvEncodeAPI.h similarity index 100% rename from sys/nvenc/nvEncodeAPI.h rename to sys/nvcodec/nvEncodeAPI.h diff --git a/sys/nvdec/nvcuvid.h b/sys/nvcodec/nvcuvid.h similarity index 100% rename from sys/nvdec/nvcuvid.h rename to sys/nvcodec/nvcuvid.h diff --git a/sys/nvdec/plugin.c b/sys/nvcodec/plugin.c similarity index 74% rename from sys/nvdec/plugin.c rename to sys/nvcodec/plugin.c index 6a081497ff..ee55ff3d9a 100644 --- a/sys/nvdec/plugin.c +++ b/sys/nvcodec/plugin.c @@ -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) diff --git a/sys/nvdec/Makefile.am b/sys/nvdec/Makefile.am deleted file mode 100644 index de41d0243f..0000000000 --- a/sys/nvdec/Makefile.am +++ /dev/null @@ -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) diff --git a/sys/nvdec/meson.build b/sys/nvdec/meson.build deleted file mode 100644 index 810a139a10..0000000000 --- a/sys/nvdec/meson.build +++ /dev/null @@ -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 - diff --git a/sys/nvenc/Makefile.am b/sys/nvenc/Makefile.am deleted file mode 100644 index 7bdd1b3d48..0000000000 --- a/sys/nvenc/Makefile.am +++ /dev/null @@ -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) diff --git a/sys/nvenc/README b/sys/nvenc/README deleted file mode 100644 index 62a52d1984..0000000000 --- a/sys/nvenc/README +++ /dev/null @@ -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 diff --git a/sys/nvenc/TODO b/sys/nvenc/TODO deleted file mode 100644 index 27422cedf3..0000000000 --- a/sys/nvenc/TODO +++ /dev/null @@ -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 diff --git a/sys/nvenc/meson.build b/sys/nvenc/meson.build deleted file mode 100644 index a652ccc37e..0000000000 --- a/sys/nvenc/meson.build +++ /dev/null @@ -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] - diff --git a/tests/check/Makefile.am b/tests/check/Makefile.am index 14a7a48f64..c36fa9f0b4 100644 --- a/tests/check/Makefile.am +++ b/tests/check/Makefile.am @@ -234,7 +234,7 @@ else check_msdk= endif -if USE_NVENC +if USE_NVCODEC check_nvenc=elements/nvenc else check_nvenc= diff --git a/tests/check/meson.build b/tests/check/meson.build index 25606df581..9987fe458c 100644 --- a/tests/check/meson.build +++ b/tests/check/meson.build @@ -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']],