xref: /OK3568_Linux_fs/buildroot/package/libv4l/0006-Support-builtin-v4l-plugins.patch (revision 4882a59341e53eb6f0b4789bf948001014eff981)
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