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

Reply via email to