On Wed, 21 Feb 2018, Maksym Veremeyenko wrote:
21.02.2018 0:39, Carl Eugen Hoyos пише:
2018-02-20 23:35 GMT+01:00 Marton Balint <c...@passwd.hu>:
On Tue, 20 Feb 2018, Carl Eugen Hoyos wrote:
2018-02-20 17:32 GMT+01:00 Maksym Veremeyenko <ve...@m1stereo.tv>:
attached patch implement dynamic loading of NewTek library and
drop dependencies from NewTek SDK (if previous patch with
including headers applied)
This patch is not ok assuming the runtime library is not open
source and has a license compatible with the GPL.
The patch might has merits even if the library remains in the
NONFREE section, no?
It might, I do not immediately see them, though.
patch without altering *EXTERNAL_LIBRARY_NONFREE_LIST* has any chance to
be reviewed?
Sure:
From 8c0337878bdb8a1ccbc56ede42686e2a4d8e882e Mon Sep 17 00:00:00 2001
From: Maksym Veremeyenko <ve...@m1.tv>
Date: Tue, 20 Feb 2018 17:16:46 +0200
Subject: [PATCH 2/2] Implement dynamic loading of NewTek NDI library
---
configure | 8 +--
libavdevice/Makefile | 4 +-
libavdevice/libndi_newtek_common.c | 105 +++++++++++++++++++++++++++++++++++++
libavdevice/libndi_newtek_common.h | 4 +-
libavdevice/libndi_newtek_dec.c | 32 ++++++-----
libavdevice/libndi_newtek_enc.c | 16 ++++--
6 files changed, 144 insertions(+), 25 deletions(-)
create mode 100644 libavdevice/libndi_newtek_common.c
diff --git a/configure b/configure
index 013308c..4782c77 100755
--- a/configure
+++ b/configure
@@ -1569,7 +1569,6 @@ EXTERNAL_LIBRARY_GPL_LIST="
EXTERNAL_LIBRARY_NONFREE_LIST="
decklink
- libndi_newtek
libfdk_aac
openssl
libtls
@@ -1648,6 +1647,7 @@ EXTERNAL_LIBRARY_LIST="
mediacodec
openal
opengl
+ libndi_newtek
"
Some people disagree with this, so better leave it in NONFREE for now.
HWACCEL_AUTODETECT_LIBRARY_LIST="
@@ -3093,10 +3093,11 @@ decklink_indev_deps="decklink threads"
decklink_indev_extralibs="-lstdc++"
decklink_outdev_deps="decklink threads"
decklink_outdev_extralibs="-lstdc++"
+libndi_newtek_deps_any="libdl LoadLibrary"
libndi_newtek_indev_deps="libndi_newtek"
-libndi_newtek_indev_extralibs="-lndi"
+libndi_newtek_indev_extralibs=""
I believe you can simply delete this line.
libndi_newtek_outdev_deps="libndi_newtek"
-libndi_newtek_outdev_extralibs="-lndi"
+libndi_newtek_outdev_extralibs=""
And this.
dshow_indev_deps="IBaseFilter"
dshow_indev_extralibs="-lpsapi -lole32 -lstrmiids -luuid -loleaut32 -lshlwapi"
fbdev_indev_deps="linux_fb_h"
@@ -5866,7 +5867,6 @@ enabled cuda_sdk && require cuda_sdk cuda.h
cuCtxCreate -lcuda
enabled chromaprint && require chromaprint chromaprint.h
chromaprint_get_version -lchromaprint
enabled decklink && { require_header DeckLinkAPI.h &&
{ check_cpp_condition DeckLinkAPIVersion.h
"BLACKMAGIC_DECKLINK_API_VERSION >= 0x0a060100" || die "ERROR: Decklink API version
must be >= 10.6.1."; } }
-enabled libndi_newtek && require_header Processing.NDI.Lib.h
As other already pointed out, external headers in ffmpeg source tree are not
welcome anymore, so I guess you should keep this check. Maybe you should also
check the version of the headers, because you require SDK version V3 from
now on, right?
enabled frei0r && require_header frei0r.h
enabled gmp && require gmp gmp.h mpz_export -lgmp
enabled gnutls && require_pkg_config gnutls gnutls gnutls/gnutls.h
gnutls_global_init
diff --git a/libavdevice/Makefile b/libavdevice/Makefile
index 8228d62..2d3322e 100644
--- a/libavdevice/Makefile
+++ b/libavdevice/Makefile
@@ -19,8 +19,8 @@ OBJS-$(CONFIG_BKTR_INDEV) += bktr.o
OBJS-$(CONFIG_CACA_OUTDEV) += caca.o
OBJS-$(CONFIG_DECKLINK_OUTDEV) += decklink_enc.o decklink_enc_c.o
decklink_common.o
OBJS-$(CONFIG_DECKLINK_INDEV) += decklink_dec.o decklink_dec_c.o
decklink_common.o
-OBJS-$(CONFIG_LIBNDI_NEWTEK_OUTDEV) += libndi_newtek_enc.o
-OBJS-$(CONFIG_LIBNDI_NEWTEK_INDEV) += libndi_newtek_dec.o
+OBJS-$(CONFIG_LIBNDI_NEWTEK_OUTDEV) += libndi_newtek_enc.o
libndi_newtek_common.o
+OBJS-$(CONFIG_LIBNDI_NEWTEK_INDEV) += libndi_newtek_dec.o
libndi_newtek_common.o
OBJS-$(CONFIG_DSHOW_INDEV) += dshow_crossbar.o dshow.o
dshow_enummediatypes.o \
dshow_enumpins.o dshow_filter.o \
dshow_pin.o dshow_common.o
diff --git a/libavdevice/libndi_newtek_common.c
b/libavdevice/libndi_newtek_common.c
new file mode 100644
index 0000000..5202993
--- /dev/null
+++ b/libavdevice/libndi_newtek_common.c
@@ -0,0 +1,105 @@
+/*
+ * NewTek NDI common code
+ * Copyright (c) 2018 Maksym Veremeyenko
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "libavformat/avformat.h"
+#include "libavformat/internal.h"
+#include "libavutil/opt.h"
+#include "libavutil/imgutils.h"
+
+#ifdef _WIN32
+#include <windows.h>
+#else
+#include <dlfcn.h>
+#endif
+
+#include "libndi_newtek_common.h"
+
+#define NDI_LIB_LOAD_ERROR_TEXT "\nPlease re-install the NewTek NDI Runtimes from "
NDILIB_REDIST_URL " to use this functionality."
+
+const NDIlib_v3* ndi_lib_load(AVFormatContext *avctx) {
Use the ff_ prefix for global functions.
+ char *path = NULL, *e;
+ const NDIlib_v3* (*NDIlib_v3_load)(void) = NULL;
+#ifdef _WIN32
+ HMODULE
+#else
+ void*
+#endif
+ hNDILib;
The library handle should be returned, and freed when the device is freed,
otherwise you are leaking it.
+
+ e = getenv(NDILIB_REDIST_FOLDER);
+ if (!e) {
+ path = av_strdup(NDILIB_LIBRARY_NAME);
+ if (!path)
+ return NULL;
+ }
+ else {
+ int s = strlen(NDILIB_LIBRARY_NAME) + 1 + strlen(e) + 1;
+ path = av_malloc(s);
+ if (!path)
+ return NULL;
+ snprintf(path, s, "%s"
+#ifdef _WIN32
+ "\\"
+#else
+ "/"
+#endif
+ "%s", e, NDILIB_LIBRARY_NAME);
+ }
You can use a simpler approach to do this using av_asprintf which
allocates the result (you need to define DS to "\\" or "/" depending on
arch):
if (e)
path = av_asprintf("%s%s%s", e, DS, NDILIB_LIBRARY_NAME);
else
path = av_strdup(NDILIB_LIBRARY_NAME);
+
+
+#ifdef _WIN32
+ /* Try to load the library */
+ hNDILib = LoadLibrary(path);
+
+ if (!hNDILib)
+ av_log(avctx, AV_LOG_ERROR, "LoadLibrary(%s) failed. " NDI_LIB_LOAD_ERROR_TEXT
"\n", path);
+ else {
+
+ /* get NDIlib_v3_load address */
+ *((FARPROC*)&NDIlib_v3_load) = GetProcAddress(hNDILib,
"NDIlib_v3_load");
+
+ if (!NDIlib_v3_load) {
+ av_log(avctx, AV_LOG_ERROR, "GetProcAddress(NDIlib_v3_load) failed in file [%s].
" NDI_LIB_LOAD_ERROR_TEXT "\n", path);
+ FreeLibrary(hNDILib);
+ }
+ }
+#else
+ /* Try to load the library */
+ hNDILib = dlopen(path, RTLD_LOCAL | RTLD_LAZY);
+
+ if (!hNDILib)
+ av_log(avctx, AV_LOG_ERROR, "dlopen(%s) failed. " NDI_LIB_LOAD_ERROR_TEXT
"\n", path);
+ else {
+
+ /* get NDIlib_v3_load address */
+ *((void**)&NDIlib_v3_load) = dlsym(hNDILib, "NDIlib_v3_load");
+
+ if (!NDIlib_v3_load) {
+ av_log(avctx, AV_LOG_ERROR, "dlsym(NDIlib_v3_load) failed in file[%s]. "
NDI_LIB_LOAD_ERROR_TEXT "\n", path);
+ dlclose(hNDILib);
+ }
+ }
+#endif
You should be able to load the library using common code if you use the
compat/w32dlfcn.h wrapper for WIN32, similarly how amfenc or avisynth does it.
However, the win32 wrapper expects a single library name, so you might
have to extend the wrapper so that it detects if there is a backslash in
the name, and act accordingly.
Regards,
Marton
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel