1From af8250adf4cdb6ba10c0d5560eb9cd974fbe3c93 Mon Sep 17 00:00:00 2001 2From: Jeffy Chen <jeffy.chen@rock-chips.com> 3Date: Tue, 14 Dec 2021 17:09:52 +0800 4Subject: [PATCH 6/7] Support builtin v4l plugins 5 6Use --enable-builtin-plugins to enable it. 7 8Only support mplane plugin for now. 9 10Signed-off-by: Jeffy Chen <jeffy.chen@rock-chips.com> 11--- 12 configure.ac | 13 ++++++ 13 lib/Makefile.am | 4 +- 14 lib/libv4l-mplane/Makefile.am | 9 ++++ 15 lib/libv4l-mplane/libv4l-mplane.c | 4 ++ 16 lib/libv4l2/Makefile.am | 3 ++ 17 lib/libv4l2/libv4l2-priv.h | 16 +++---- 18 lib/libv4l2/libv4l2.c | 73 +++++++++++++++++++++++++++++++ 19 lib/libv4l2/v4l2-plugin.c | 8 ++-- 20 8 files changed, 116 insertions(+), 14 deletions(-) 21 22diff --git a/configure.ac b/configure.ac 23index 98bbbeb..7bfc393 100644 24--- a/configure.ac 25+++ b/configure.ac 26@@ -539,6 +539,14 @@ AC_ARG_ENABLE(bpf, 27 esac] 28 ) 29 30+AC_ARG_ENABLE(builtin-plugins, 31+ AS_HELP_STRING([--enable-builtin-plugins], [enable builtin libv4l plugins]), 32+ [case "${enableval}" in 33+ yes | no ) ;; 34+ *) AC_MSG_ERROR(bad value ${enableval} for --enable-builtin-plugins) ;; 35+ esac] 36+) 37+ 38 PKG_CHECK_MODULES([SDL2], [sdl2 SDL2_image], [sdl_pc=yes], [sdl_pc=no]) 39 AM_CONDITIONAL([HAVE_SDL], [test x$sdl_pc = xyes]) 40 41@@ -555,6 +563,7 @@ AM_CONDITIONAL([WITH_V4LUTILS], [test x$enable_v4l_utils != xno -a x$linux_o 42 AM_CONDITIONAL([WITH_QV4L2], [test x${qt_pkgconfig} = xtrue -a x$enable_qv4l2 != xno]) 43 AM_CONDITIONAL([WITH_QVIDCAP], [test x${qt_desktop_opengl} = xyes -a x$enable_qvidcap != xno]) 44 AM_CONDITIONAL([WITH_V4L_PLUGINS], [test x$enable_dyn_libv4l != xno -a x$enable_shared != xno]) 45+AM_CONDITIONAL([WITH_V4L_BUILTIN_PLUGINS], [test x$enable_builtin_plugins = xyes]) 46 AM_CONDITIONAL([WITH_V4L_WRAPPERS], [test x$enable_dyn_libv4l != xno -a x$enable_shared != xno]) 47 AM_CONDITIONAL([WITH_QTGL], [test x${qt_desktop_opengl} = xyes]) 48 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]) 49@@ -607,6 +616,9 @@ AM_COND_IF([WITH_QVIDCAP], [USE_QVIDCAP="yes"], [USE_QVIDCAP="no"]) 50 AM_COND_IF([WITH_V4L_PLUGINS], [USE_V4L_PLUGINS="yes" 51 AC_DEFINE([HAVE_V4L_PLUGINS], [1], [V4L plugin support enabled])], 52 [USE_V4L_PLUGINS="no"]) 53+AM_COND_IF([WITH_V4L_BUILTIN_PLUGINS], [USE_V4L_BUILTIN_PLUGINS="yes" 54+ AC_DEFINE([HAVE_V4L_BUILTIN_PLUGINS], [1], [V4L builtin plugin support enabled])], 55+ [USE_V4L_BUILTIN_PLUGINS="no"]) 56 AM_COND_IF([WITH_V4L_WRAPPERS], [USE_V4L_WRAPPERS="yes"], [USE_V4L_WRAPPERS="no"]) 57 AM_COND_IF([WITH_GCONV], [USE_GCONV="yes"], [USE_GCONV="no"]) 58 AM_COND_IF([WITH_V4L2_CTL_LIBV4L], [USE_V4L2_CTL_LIBV4L="yes"], [USE_V4L2_CTL_LIBV4L="no"]) 59@@ -653,6 +665,7 @@ compile time options summary 60 61 dynamic libv4l : $USE_DYN_LIBV4L 62 v4l_plugins : $USE_V4L_PLUGINS 63+ v4l_builtin_plugins : $USE_V4L_BUILTIN_PLUGINS 64 v4l_wrappers : $USE_V4L_WRAPPERS 65 libdvbv5 : $USE_LIBDVBV5 66 dvbv5-daemon : $USE_DVBV5_REMOTE 67diff --git a/lib/Makefile.am b/lib/Makefile.am 68index a105c95..4952d6d 100644 69--- a/lib/Makefile.am 70+++ b/lib/Makefile.am 71@@ -1,9 +1,9 @@ 72 SUBDIRS = \ 73+ libv4l-mplane \ 74 libv4lconvert \ 75 libv4l2 \ 76 libv4l1 \ 77- libv4l2rds \ 78- libv4l-mplane 79+ libv4l2rds 80 81 if WITH_LIBDVBV5 82 SUBDIRS += \ 83diff --git a/lib/libv4l-mplane/Makefile.am b/lib/libv4l-mplane/Makefile.am 84index 5264ecf..4c0ba0a 100644 85--- a/lib/libv4l-mplane/Makefile.am 86+++ b/lib/libv4l-mplane/Makefile.am 87@@ -1,7 +1,16 @@ 88+if WITH_V4L_BUILTIN_PLUGINS 89+noinst_LTLIBRARIES = libv4l-mplane.la 90+else 91 if WITH_V4L_PLUGINS 92 libv4l2plugin_LTLIBRARIES = libv4l-mplane.la 93 endif 94+endif 95 96 libv4l_mplane_la_SOURCES = libv4l-mplane.c 97+if WITH_V4L_BUILTIN_PLUGINS 98+libv4l_mplane_la_CPPFLAGS = -static 99+libv4l_mplane_la_LDFLAGS = -static 100+else 101 libv4l_mplane_la_CPPFLAGS = $(CFLAG_VISIBILITY) 102 libv4l_mplane_la_LDFLAGS = -avoid-version -module -shared -export-dynamic -lpthread 103+endif 104diff --git a/lib/libv4l-mplane/libv4l-mplane.c b/lib/libv4l-mplane/libv4l-mplane.c 105index db22b0b..fcd522e 100644 106--- a/lib/libv4l-mplane/libv4l-mplane.c 107+++ b/lib/libv4l-mplane/libv4l-mplane.c 108@@ -609,7 +609,11 @@ static ssize_t plugin_write(void *dev_ops_priv, int fd, const void *buf, 109 return SYS_WRITE(fd, buf, len); 110 } 111 112+#ifdef HAVE_V4L_BUILTIN_PLUGINS 113+const struct libv4l_dev_ops libv4l2_plugin_mplane = { 114+#else 115 PLUGIN_PUBLIC const struct libv4l_dev_ops libv4l2_plugin = { 116+#endif 117 .init = &plugin_init, 118 .close = &plugin_close, 119 .ioctl = &plugin_ioctl, 120diff --git a/lib/libv4l2/Makefile.am b/lib/libv4l2/Makefile.am 121index 3a1bb90..1250d84 100644 122--- a/lib/libv4l2/Makefile.am 123+++ b/lib/libv4l2/Makefile.am 124@@ -23,6 +23,9 @@ endif 125 libv4l2_la_CPPFLAGS = $(CFLAG_VISIBILITY) $(ENFORCE_LIBV4L_STATIC) 126 libv4l2_la_LDFLAGS = $(LIBV4L2_VERSION) -lpthread $(DLOPEN_LIBS) $(ENFORCE_LIBV4L_STATIC) 127 libv4l2_la_LIBADD = ../libv4lconvert/libv4lconvert.la 128+if WITH_V4L_BUILTIN_PLUGINS 129+libv4l2_la_LIBADD += ../libv4l-mplane/libv4l-mplane.la 130+endif 131 132 v4l2convert_la_SOURCES = v4l2convert.c 133 v4l2convert_la_LIBADD = libv4l2.la 134diff --git a/lib/libv4l2/libv4l2-priv.h b/lib/libv4l2/libv4l2-priv.h 135index cce6de4..cc8c4f5 100644 136--- a/lib/libv4l2/libv4l2-priv.h 137+++ b/lib/libv4l2/libv4l2-priv.h 138@@ -109,20 +109,20 @@ struct v4l2_dev_info { 139 140 /* From v4l2-plugin.c */ 141 #if defined(HAVE_V4L_PLUGINS) 142-void v4l2_plugin_init(int fd, void **plugin_lib_ret, void **plugin_priv_ret, 143- const struct libv4l_dev_ops **dev_ops_ret); 144-void v4l2_plugin_cleanup(void *plugin_lib, void *plugin_priv, 145- const struct libv4l_dev_ops *dev_ops); 146+void v4l2_dyn_plugin_init(int fd, void **plugin_lib_ret, void **plugin_priv_ret, 147+ const struct libv4l_dev_ops **dev_ops_ret); 148+void v4l2_dyn_plugin_cleanup(void *plugin_lib, void *plugin_priv, 149+ const struct libv4l_dev_ops *dev_ops); 150 #else 151-static inline void v4l2_plugin_init(int fd, void **plugin_lib_ret, void **plugin_priv_ret, 152- const struct libv4l_dev_ops **dev_ops_ret) 153+static inline void v4l2_dyn_plugin_init(int fd, void **plugin_lib_ret, void **plugin_priv_ret, 154+ const struct libv4l_dev_ops **dev_ops_ret) 155 { 156 *dev_ops_ret = v4lconvert_get_default_dev_ops(); 157 *plugin_lib_ret = NULL; 158 *plugin_priv_ret = NULL; 159 } 160-static inline void v4l2_plugin_cleanup(void *plugin_lib, void *plugin_priv, 161- const struct libv4l_dev_ops *dev_ops) 162+static inline void v4l2_dyn_plugin_cleanup(void *plugin_lib, void *plugin_priv, 163+ const struct libv4l_dev_ops *dev_ops) 164 { 165 } 166 #endif /* WITH_V4L_PLUGINS */ 167diff --git a/lib/libv4l2/libv4l2.c b/lib/libv4l2/libv4l2.c 168index 0b17888..949a020 100644 169--- a/lib/libv4l2/libv4l2.c 170+++ b/lib/libv4l2/libv4l2.c 171@@ -74,6 +74,8 @@ 172 #include "libv4l2-priv.h" 173 #include "libv4l-plugin.h" 174 175+#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) 176+ 177 /* Note these flags are stored together with the flags passed to v4l2_fd_open() 178 in v4l2_dev_info's flags member, so care should be taken that the do not 179 use the same bits! */ 180@@ -618,6 +620,77 @@ static void v4l2_update_fps(int index, struct v4l2_streamparm *parm) 181 devices[index].fps = 0; 182 } 183 184+#ifdef HAVE_V4L_BUILTIN_PLUGINS 185+extern const struct libv4l_dev_ops libv4l2_plugin_mplane; 186+ 187+void v4l2_builtin_plugin_init(int fd, void **plugin_priv_ret, 188+ const struct libv4l_dev_ops **dev_ops_ret) 189+{ 190+ const struct libv4l_dev_ops *builtin_plugins[] = { 191+ &libv4l2_plugin_mplane, 192+ }; 193+ const struct libv4l_dev_ops *libv4l2_plugin = NULL; 194+ int i; 195+ 196+ *dev_ops_ret = NULL; 197+ *plugin_priv_ret = NULL; 198+ 199+ for (i = 0; i < ARRAY_SIZE(builtin_plugins); i++) { 200+ V4L2_LOG("PLUGIN: try builtin(%d);\n", i); 201+ 202+ libv4l2_plugin = builtin_plugins[i]; 203+ 204+ if (!libv4l2_plugin->init || 205+ !libv4l2_plugin->close || 206+ !libv4l2_plugin->ioctl) { 207+ V4L2_LOG("PLUGIN: does not have all mandatory ops\n"); 208+ continue; 209+ } 210+ 211+ *plugin_priv_ret = libv4l2_plugin->init(fd); 212+ if (!*plugin_priv_ret) { 213+ V4L2_LOG("PLUGIN: plugin init() returned NULL\n"); 214+ continue; 215+ } 216+ 217+ *dev_ops_ret = libv4l2_plugin; 218+ break; 219+ } 220+} 221+ 222+void v4l2_builtin_plugin_cleanup(void *plugin_priv, 223+ const struct libv4l_dev_ops *dev_ops) 224+{ 225+ dev_ops->close(plugin_priv); 226+} 227+#endif /* HAVE_V4L_PLUGINS */ 228+ 229+void v4l2_plugin_init(int fd, void **plugin_lib_ret, void **plugin_priv_ret, 230+ const struct libv4l_dev_ops **dev_ops_ret) 231+{ 232+#ifdef HAVE_V4L_BUILTIN_PLUGINS 233+ *plugin_lib_ret = NULL; 234+ v4l2_builtin_plugin_init(fd, plugin_priv_ret, dev_ops_ret); 235+ if (*dev_ops_ret) 236+ return; 237+#endif 238+ 239+ v4l2_dyn_plugin_init(fd, plugin_lib_ret, plugin_priv_ret, dev_ops_ret); 240+} 241+ 242+void v4l2_plugin_cleanup(void *plugin_lib, void *plugin_priv, 243+ const struct libv4l_dev_ops *dev_ops) 244+{ 245+#ifdef HAVE_V4L_BUILTIN_PLUGINS 246+ if (!plugin_lib) { 247+ v4l2_builtin_plugin_cleanup(plugin_priv, dev_ops); 248+ return; 249+ } 250+#endif 251+ 252+ v4l2_dyn_plugin_cleanup(plugin_lib, plugin_priv, dev_ops); 253+} 254+ 255 int v4l2_open(const char *file, int oflag, ...) 256 { 257 int fd; 258diff --git a/lib/libv4l2/v4l2-plugin.c b/lib/libv4l2/v4l2-plugin.c 259index ff42eed..f65baaa 100644 260--- a/lib/libv4l2/v4l2-plugin.c 261+++ b/lib/libv4l2/v4l2-plugin.c 262@@ -48,8 +48,8 @@ 263 264 #define PLUGINS_PATTERN LIBV4L2_PLUGIN_DIR "/*.so" 265 266-void v4l2_plugin_init(int fd, void **plugin_lib_ret, void **plugin_priv_ret, 267- const struct libv4l_dev_ops **dev_ops_ret) 268+void v4l2_dyn_plugin_init(int fd, void **plugin_lib_ret, void **plugin_priv_ret, 269+ const struct libv4l_dev_ops **dev_ops_ret) 270 { 271 char *error; 272 int glob_ret, i; 273@@ -110,8 +110,8 @@ leave: 274 globfree(&globbuf); 275 } 276 277-void v4l2_plugin_cleanup(void *plugin_lib, void *plugin_priv, 278- const struct libv4l_dev_ops *dev_ops) 279+void v4l2_dyn_plugin_cleanup(void *plugin_lib, void *plugin_priv, 280+ const struct libv4l_dev_ops *dev_ops) 281 { 282 if (plugin_lib) { 283 dev_ops->close(plugin_priv); 284-- 2852.20.1 286 287