HYL_OK3568_LINUX/buildroot/package/libv4l/0006-Support-builtin-v4l-plugins.patch
2025-05-10 21:49:39 +08:00

287 lines
9.7 KiB
Diff

From af8250adf4cdb6ba10c0d5560eb9cd974fbe3c93 Mon Sep 17 00:00:00 2001
From: Jeffy Chen <jeffy.chen@rock-chips.com>
Date: Tue, 14 Dec 2021 17:09:52 +0800
Subject: [PATCH 6/7] Support builtin v4l plugins
Use --enable-builtin-plugins to enable it.
Only support mplane plugin for now.
Signed-off-by: Jeffy Chen <jeffy.chen@rock-chips.com>
---
configure.ac | 13 ++++++
lib/Makefile.am | 4 +-
lib/libv4l-mplane/Makefile.am | 9 ++++
lib/libv4l-mplane/libv4l-mplane.c | 4 ++
lib/libv4l2/Makefile.am | 3 ++
lib/libv4l2/libv4l2-priv.h | 16 +++----
lib/libv4l2/libv4l2.c | 73 +++++++++++++++++++++++++++++++
lib/libv4l2/v4l2-plugin.c | 8 ++--
8 files changed, 116 insertions(+), 14 deletions(-)
diff --git a/configure.ac b/configure.ac
index 98bbbeb..7bfc393 100644
--- a/configure.ac
+++ b/configure.ac
@@ -539,6 +539,14 @@ AC_ARG_ENABLE(bpf,
esac]
)
+AC_ARG_ENABLE(builtin-plugins,
+ AS_HELP_STRING([--enable-builtin-plugins], [enable builtin libv4l plugins]),
+ [case "${enableval}" in
+ yes | no ) ;;
+ *) AC_MSG_ERROR(bad value ${enableval} for --enable-builtin-plugins) ;;
+ esac]
+)
+
PKG_CHECK_MODULES([SDL2], [sdl2 SDL2_image], [sdl_pc=yes], [sdl_pc=no])
AM_CONDITIONAL([HAVE_SDL], [test x$sdl_pc = xyes])
@@ -555,6 +563,7 @@ AM_CONDITIONAL([WITH_V4LUTILS], [test x$enable_v4l_utils != xno -a x$linux_o
AM_CONDITIONAL([WITH_QV4L2], [test x${qt_pkgconfig} = xtrue -a x$enable_qv4l2 != xno])
AM_CONDITIONAL([WITH_QVIDCAP], [test x${qt_desktop_opengl} = xyes -a x$enable_qvidcap != xno])
AM_CONDITIONAL([WITH_V4L_PLUGINS], [test x$enable_dyn_libv4l != xno -a x$enable_shared != xno])
+AM_CONDITIONAL([WITH_V4L_BUILTIN_PLUGINS], [test x$enable_builtin_plugins = xyes])
AM_CONDITIONAL([WITH_V4L_WRAPPERS], [test x$enable_dyn_libv4l != xno -a x$enable_shared != xno])
AM_CONDITIONAL([WITH_QTGL], [test x${qt_desktop_opengl} = xyes])
AM_CONDITIONAL([WITH_GCONV], [test x$enable_gconv = xyes -a x$enable_shared = xyes -a x$with_gconvdir != x -a -f $with_gconvdir/gconv-modules])
@@ -607,6 +616,9 @@ AM_COND_IF([WITH_QVIDCAP], [USE_QVIDCAP="yes"], [USE_QVIDCAP="no"])
AM_COND_IF([WITH_V4L_PLUGINS], [USE_V4L_PLUGINS="yes"
AC_DEFINE([HAVE_V4L_PLUGINS], [1], [V4L plugin support enabled])],
[USE_V4L_PLUGINS="no"])
+AM_COND_IF([WITH_V4L_BUILTIN_PLUGINS], [USE_V4L_BUILTIN_PLUGINS="yes"
+ AC_DEFINE([HAVE_V4L_BUILTIN_PLUGINS], [1], [V4L builtin plugin support enabled])],
+ [USE_V4L_BUILTIN_PLUGINS="no"])
AM_COND_IF([WITH_V4L_WRAPPERS], [USE_V4L_WRAPPERS="yes"], [USE_V4L_WRAPPERS="no"])
AM_COND_IF([WITH_GCONV], [USE_GCONV="yes"], [USE_GCONV="no"])
AM_COND_IF([WITH_V4L2_CTL_LIBV4L], [USE_V4L2_CTL_LIBV4L="yes"], [USE_V4L2_CTL_LIBV4L="no"])
@@ -653,6 +665,7 @@ compile time options summary
dynamic libv4l : $USE_DYN_LIBV4L
v4l_plugins : $USE_V4L_PLUGINS
+ v4l_builtin_plugins : $USE_V4L_BUILTIN_PLUGINS
v4l_wrappers : $USE_V4L_WRAPPERS
libdvbv5 : $USE_LIBDVBV5
dvbv5-daemon : $USE_DVBV5_REMOTE
diff --git a/lib/Makefile.am b/lib/Makefile.am
index a105c95..4952d6d 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -1,9 +1,9 @@
SUBDIRS = \
+ libv4l-mplane \
libv4lconvert \
libv4l2 \
libv4l1 \
- libv4l2rds \
- libv4l-mplane
+ libv4l2rds
if WITH_LIBDVBV5
SUBDIRS += \
diff --git a/lib/libv4l-mplane/Makefile.am b/lib/libv4l-mplane/Makefile.am
index 5264ecf..4c0ba0a 100644
--- a/lib/libv4l-mplane/Makefile.am
+++ b/lib/libv4l-mplane/Makefile.am
@@ -1,7 +1,16 @@
+if WITH_V4L_BUILTIN_PLUGINS
+noinst_LTLIBRARIES = libv4l-mplane.la
+else
if WITH_V4L_PLUGINS
libv4l2plugin_LTLIBRARIES = libv4l-mplane.la
endif
+endif
libv4l_mplane_la_SOURCES = libv4l-mplane.c
+if WITH_V4L_BUILTIN_PLUGINS
+libv4l_mplane_la_CPPFLAGS = -static
+libv4l_mplane_la_LDFLAGS = -static
+else
libv4l_mplane_la_CPPFLAGS = $(CFLAG_VISIBILITY)
libv4l_mplane_la_LDFLAGS = -avoid-version -module -shared -export-dynamic -lpthread
+endif
diff --git a/lib/libv4l-mplane/libv4l-mplane.c b/lib/libv4l-mplane/libv4l-mplane.c
index db22b0b..fcd522e 100644
--- a/lib/libv4l-mplane/libv4l-mplane.c
+++ b/lib/libv4l-mplane/libv4l-mplane.c
@@ -609,7 +609,11 @@ static ssize_t plugin_write(void *dev_ops_priv, int fd, const void *buf,
return SYS_WRITE(fd, buf, len);
}
+#ifdef HAVE_V4L_BUILTIN_PLUGINS
+const struct libv4l_dev_ops libv4l2_plugin_mplane = {
+#else
PLUGIN_PUBLIC const struct libv4l_dev_ops libv4l2_plugin = {
+#endif
.init = &plugin_init,
.close = &plugin_close,
.ioctl = &plugin_ioctl,
diff --git a/lib/libv4l2/Makefile.am b/lib/libv4l2/Makefile.am
index 3a1bb90..1250d84 100644
--- a/lib/libv4l2/Makefile.am
+++ b/lib/libv4l2/Makefile.am
@@ -23,6 +23,9 @@ endif
libv4l2_la_CPPFLAGS = $(CFLAG_VISIBILITY) $(ENFORCE_LIBV4L_STATIC)
libv4l2_la_LDFLAGS = $(LIBV4L2_VERSION) -lpthread $(DLOPEN_LIBS) $(ENFORCE_LIBV4L_STATIC)
libv4l2_la_LIBADD = ../libv4lconvert/libv4lconvert.la
+if WITH_V4L_BUILTIN_PLUGINS
+libv4l2_la_LIBADD += ../libv4l-mplane/libv4l-mplane.la
+endif
v4l2convert_la_SOURCES = v4l2convert.c
v4l2convert_la_LIBADD = libv4l2.la
diff --git a/lib/libv4l2/libv4l2-priv.h b/lib/libv4l2/libv4l2-priv.h
index cce6de4..cc8c4f5 100644
--- a/lib/libv4l2/libv4l2-priv.h
+++ b/lib/libv4l2/libv4l2-priv.h
@@ -109,20 +109,20 @@ struct v4l2_dev_info {
/* From v4l2-plugin.c */
#if defined(HAVE_V4L_PLUGINS)
-void v4l2_plugin_init(int fd, void **plugin_lib_ret, void **plugin_priv_ret,
- const struct libv4l_dev_ops **dev_ops_ret);
-void v4l2_plugin_cleanup(void *plugin_lib, void *plugin_priv,
- const struct libv4l_dev_ops *dev_ops);
+void v4l2_dyn_plugin_init(int fd, void **plugin_lib_ret, void **plugin_priv_ret,
+ const struct libv4l_dev_ops **dev_ops_ret);
+void v4l2_dyn_plugin_cleanup(void *plugin_lib, void *plugin_priv,
+ const struct libv4l_dev_ops *dev_ops);
#else
-static inline void v4l2_plugin_init(int fd, void **plugin_lib_ret, void **plugin_priv_ret,
- const struct libv4l_dev_ops **dev_ops_ret)
+static inline void v4l2_dyn_plugin_init(int fd, void **plugin_lib_ret, void **plugin_priv_ret,
+ const struct libv4l_dev_ops **dev_ops_ret)
{
*dev_ops_ret = v4lconvert_get_default_dev_ops();
*plugin_lib_ret = NULL;
*plugin_priv_ret = NULL;
}
-static inline void v4l2_plugin_cleanup(void *plugin_lib, void *plugin_priv,
- const struct libv4l_dev_ops *dev_ops)
+static inline void v4l2_dyn_plugin_cleanup(void *plugin_lib, void *plugin_priv,
+ const struct libv4l_dev_ops *dev_ops)
{
}
#endif /* WITH_V4L_PLUGINS */
diff --git a/lib/libv4l2/libv4l2.c b/lib/libv4l2/libv4l2.c
index 0b17888..949a020 100644
--- a/lib/libv4l2/libv4l2.c
+++ b/lib/libv4l2/libv4l2.c
@@ -74,6 +74,8 @@
#include "libv4l2-priv.h"
#include "libv4l-plugin.h"
+#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
+
/* Note these flags are stored together with the flags passed to v4l2_fd_open()
in v4l2_dev_info's flags member, so care should be taken that the do not
use the same bits! */
@@ -618,6 +620,77 @@ static void v4l2_update_fps(int index, struct v4l2_streamparm *parm)
devices[index].fps = 0;
}
+#ifdef HAVE_V4L_BUILTIN_PLUGINS
+extern const struct libv4l_dev_ops libv4l2_plugin_mplane;
+
+void v4l2_builtin_plugin_init(int fd, void **plugin_priv_ret,
+ const struct libv4l_dev_ops **dev_ops_ret)
+{
+ const struct libv4l_dev_ops *builtin_plugins[] = {
+ &libv4l2_plugin_mplane,
+ };
+ const struct libv4l_dev_ops *libv4l2_plugin = NULL;
+ int i;
+
+ *dev_ops_ret = NULL;
+ *plugin_priv_ret = NULL;
+
+ for (i = 0; i < ARRAY_SIZE(builtin_plugins); i++) {
+ V4L2_LOG("PLUGIN: try builtin(%d);\n", i);
+
+ libv4l2_plugin = builtin_plugins[i];
+
+ if (!libv4l2_plugin->init ||
+ !libv4l2_plugin->close ||
+ !libv4l2_plugin->ioctl) {
+ V4L2_LOG("PLUGIN: does not have all mandatory ops\n");
+ continue;
+ }
+
+ *plugin_priv_ret = libv4l2_plugin->init(fd);
+ if (!*plugin_priv_ret) {
+ V4L2_LOG("PLUGIN: plugin init() returned NULL\n");
+ continue;
+ }
+
+ *dev_ops_ret = libv4l2_plugin;
+ break;
+ }
+}
+
+void v4l2_builtin_plugin_cleanup(void *plugin_priv,
+ const struct libv4l_dev_ops *dev_ops)
+{
+ dev_ops->close(plugin_priv);
+}
+#endif /* HAVE_V4L_PLUGINS */
+
+void v4l2_plugin_init(int fd, void **plugin_lib_ret, void **plugin_priv_ret,
+ const struct libv4l_dev_ops **dev_ops_ret)
+{
+#ifdef HAVE_V4L_BUILTIN_PLUGINS
+ *plugin_lib_ret = NULL;
+ v4l2_builtin_plugin_init(fd, plugin_priv_ret, dev_ops_ret);
+ if (*dev_ops_ret)
+ return;
+#endif
+
+ v4l2_dyn_plugin_init(fd, plugin_lib_ret, plugin_priv_ret, dev_ops_ret);
+}
+
+void v4l2_plugin_cleanup(void *plugin_lib, void *plugin_priv,
+ const struct libv4l_dev_ops *dev_ops)
+{
+#ifdef HAVE_V4L_BUILTIN_PLUGINS
+ if (!plugin_lib) {
+ v4l2_builtin_plugin_cleanup(plugin_priv, dev_ops);
+ return;
+ }
+#endif
+
+ v4l2_dyn_plugin_cleanup(plugin_lib, plugin_priv, dev_ops);
+}
+
int v4l2_open(const char *file, int oflag, ...)
{
int fd;
diff --git a/lib/libv4l2/v4l2-plugin.c b/lib/libv4l2/v4l2-plugin.c
index ff42eed..f65baaa 100644
--- a/lib/libv4l2/v4l2-plugin.c
+++ b/lib/libv4l2/v4l2-plugin.c
@@ -48,8 +48,8 @@
#define PLUGINS_PATTERN LIBV4L2_PLUGIN_DIR "/*.so"
-void v4l2_plugin_init(int fd, void **plugin_lib_ret, void **plugin_priv_ret,
- const struct libv4l_dev_ops **dev_ops_ret)
+void v4l2_dyn_plugin_init(int fd, void **plugin_lib_ret, void **plugin_priv_ret,
+ const struct libv4l_dev_ops **dev_ops_ret)
{
char *error;
int glob_ret, i;
@@ -110,8 +110,8 @@ leave:
globfree(&globbuf);
}
-void v4l2_plugin_cleanup(void *plugin_lib, void *plugin_priv,
- const struct libv4l_dev_ops *dev_ops)
+void v4l2_dyn_plugin_cleanup(void *plugin_lib, void *plugin_priv,
+ const struct libv4l_dev_ops *dev_ops)
{
if (plugin_lib) {
dev_ops->close(plugin_priv);
--
2.20.1