nvenc: Add meson build with Windows support
authorSeungha Yang <seungha.yang@navercorp.com>
Thu, 22 Nov 2018 03:14:44 +0000 (12:14 +0900)
committerTim-Philipp Müller <tim@centricular.com>
Sun, 25 Nov 2018 23:31:37 +0000 (23:31 +0000)
Note that, since Nvidia does not provide nvEncodeAPI.lib file,
find_library() couldn't be used for build on Windows.
This patch changes to load nvEncodeAPI(64).dll or libnvidia-encode.so
in runtime

configure.ac
meson_options.txt
sys/meson.build
sys/nvenc/Makefile.am
sys/nvenc/gstnvenc.c
sys/nvenc/gstnvenc.h
sys/nvenc/meson.build [new file with mode: 0644]

index 5adc154..8b281c9 100644 (file)
@@ -1003,26 +1003,6 @@ AG_GST_CHECK_FEATURE(NVDEC, [nvdec], nvdec, [
 dnl *** NVENC ***
 translit(dnm, m, l) AM_CONDITIONAL(USE_NVENC, true)
 AG_GST_CHECK_FEATURE(NVENC, [NVIDIA Encode API], nvenc, [
-  dnl nvEncodeAPI.h header
-  HAVE_NVENCODEAPI_H=no
-  AC_ARG_VAR(NVENCODE_CFLAGS, [C compiler flags for NvEncodeAPI.h])
-  save_CPPFLAGS="$CPPFLAGS"
-  CPPFLAGS="$NVENCODE_CFLAGS $save_CPPFLAGS"
-  AC_CHECK_HEADER([nvEncodeAPI.h], [
-      AC_PREPROC_IFELSE([AC_LANG_SOURCE([[#include <nvEncodeAPI.h>
-          #if NVENCAPI_MAJOR_VERSION < 5
-          #error "Need nvEncodeAPI.h >= 5.0"
-          #endif
-          ]])], [
-          HAVE_NVENCODEAPI_H=yes
-          ], [
-          AC_MSG_WARN([nvEncodeAPI.h must be >= 5.0])
-          ])
-      ],
-      AC_MSG_WARN([Could not find nvEncodeAPI.h]))
-  AC_SUBST(NVENCODE_CFLAGS)
-  CPPFLAGS="$save_CPPFLAGS"
-
   dnl libnvnidia-encode library
   HAVE_NVENCODE_LIB=no
   AC_ARG_VAR(NVENCODE_LIBS, [linker flags for nvidia-encode])
@@ -1039,7 +1019,6 @@ AG_GST_CHECK_FEATURE(NVENC, [NVIDIA Encode API], nvenc, [
       -a "x$HAVE_CUDART_H" = "xyes" \
       -a "x$HAVE_CUDA_LIB" = "xyes" \
       -a "x$HAVE_CUDART_LIB" = "xyes" \
-      -a "x$HAVE_NVENCODEAPI_H" = "xyes" \
       -a "x$HAVE_NVENCODE_LIB" = "xyes"; then
     HAVE_NVENC="yes"
     if test "x$GST_GL_HAVE_API_GL" = "x1"; then
index 9695fcd..fc8bc7c 100644 (file)
@@ -114,6 +114,7 @@ option('msdk', type : 'feature', value : 'auto', description : 'Intel Media SDK
 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('openh264', type : 'feature', value : 'auto', description : 'H.264 video codec plugin')
 option('openjpeg', type : 'feature', value : 'auto', description : 'JPEG2000 image codec plugin')
 option('opensles', type : 'feature', value : 'auto', description : 'OpenSL ES audio source/sink plugin')
index 8a1363f..7b7e92d 100644 (file)
@@ -106,7 +106,9 @@ endif
 
 if cuda_dep.found() and cudart_dep.found()
   subdir('nvdec')
-  #subdir('nvenc')
+  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
\ No newline at end of file
index e77e0a3..7c23797 100644 (file)
@@ -17,15 +17,14 @@ libgstnvenc_la_CFLAGS = \
        $(GST_PBUTILS_CFLAGS) \
        $(GST_VIDEO_CFLAGS) \
        $(GST_CFLAGS) \
-       $(CUDA_CFLAGS) \
-       $(NVENCODE_CFLAGS)
+       $(CUDA_CFLAGS)
 
 libgstnvenc_la_LIBADD = \
        $(GST_PBUTILS_LIBS) \
        $(GST_VIDEO_LIBS) \
        $(GST_LIBS) \
        $(CUDA_LIBS) \
-       $(NVENCODE_LIBS)
+       $(GMODULE_NO_EXPORT_LIBS)
 
 if USE_NVENC_GST_GL
 libgstnvenc_la_CFLAGS += $(GST_GL_CFLAGS)
index a2edb7e..8fa83fc 100644 (file)
 #include "gstnvenc.h"
 #include "gstnvh264enc.h"
 #include "gstnvh265enc.h"
+#include <gmodule.h>
+
+#ifdef _WIN32
+#ifdef _WIN64
+#define NVENC_LIBRARY_NAME "nvEncodeAPI64.dll"
+#else
+#define NVENC_LIBRARY_NAME "nvEncodeAPI.dll"
+#endif
+#else
+#define NVENC_LIBRARY_NAME "libnvidia-encode.so.1"
+#endif
+
+typedef NVENCSTATUS NVENCAPI
+tNvEncodeAPICreateInstance (NV_ENCODE_API_FUNCTION_LIST * functionList);
+tNvEncodeAPICreateInstance *nvEncodeAPICreateInstance;
 
 GST_DEBUG_CATEGORY (gst_nvenc_debug);
 #define GST_CAT_DEFAULT gst_nvenc_debug
@@ -328,12 +343,35 @@ gst_nvenc_destroy_cuda_context (CUcontext ctx)
 }
 
 static gboolean
+load_nvenc_library (void)
+{
+  GModule *module;
+
+  module = g_module_open (NVENC_LIBRARY_NAME, G_MODULE_BIND_LAZY);
+  if (module == NULL) {
+    GST_ERROR ("%s", g_module_error ());
+    return FALSE;
+  }
+
+  if (!g_module_symbol (module, "NvEncodeAPICreateInstance",
+          (gpointer *) & nvEncodeAPICreateInstance)) {
+    GST_ERROR ("%s", g_module_error ());
+    return FALSE;
+  }
+
+  return TRUE;
+}
+
+static gboolean
 plugin_init (GstPlugin * plugin)
 {
   GST_DEBUG_CATEGORY_INIT (gst_nvenc_debug, "nvenc", 0, "Nvidia NVENC encoder");
 
   nvenc_api.version = NV_ENCODE_API_FUNCTION_LIST_VER;
-  if (NvEncodeAPICreateInstance (&nvenc_api) != NV_ENC_SUCCESS) {
+  if (!load_nvenc_library ())
+    return FALSE;
+
+  if (nvEncodeAPICreateInstance (&nvenc_api) != NV_ENC_SUCCESS) {
     GST_ERROR ("Failed to get NVEncodeAPI function table!");
   } else {
     GST_INFO ("Created NVEncodeAPI instance, got function table");
index e9720da..2af23ed 100644 (file)
@@ -23,7 +23,7 @@
 #include <gst/gst.h>
 #include <gst/video/video.h>
 
-#include <nvEncodeAPI.h>
+#include "nvEncodeAPI.h"
 #include <cuda.h>
 
 GST_DEBUG_CATEGORY_EXTERN (gst_nvenc_debug);
diff --git a/sys/nvenc/meson.build b/sys/nvenc/meson.build
new file mode 100644 (file)
index 0000000..2a6739f
--- /dev/null
@@ -0,0 +1,40 @@
+nvenc_sources = [
+  'gstnvbaseenc.c',
+  'gstnvenc.c',
+  'gstnvh264enc.c',
+  'gstnvh265enc.c',
+]
+
+nvenc_option = get_option('nvenc')
+if nvenc_option.disabled()
+  subdir_done()
+endif
+
+use_nvenc_gl = false
+extra_c_args = []
+
+if host_machine.system() == 'windows'
+  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)
+