[vlc-commits] v4l2: load libv4l2 dynamically where available

Rémi Denis-Courmont git at videolan.org
Sun Mar 11 21:15:51 CET 2012


vlc | branch: master | Rémi Denis-Courmont <remi at remlab.net> | Sun Mar 11 22:14:38 2012 +0200| [1faaadfcd885357a7ccde457aa4a540bb90e2185] | committer: Rémi Denis-Courmont

v4l2: load libv4l2 dynamically where available

This removes the build-time and install-time dependency.

> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=1faaadfcd885357a7ccde457aa4a540bb90e2185
---

 configure.ac                |    5 --
 modules/access/Modules.am   |    5 +-
 modules/access/v4l2/lib.c   |   89 +++++++++++++++++++++++++++++++++++++++++++
 modules/access/v4l2/v4l2.h  |   21 +++-------
 modules/access/v4l2/video.c |   29 ++------------
 5 files changed, 103 insertions(+), 46 deletions(-)

diff --git a/configure.ac b/configure.ac
index 154ec80..4244dad 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1840,11 +1840,6 @@ AS_IF([test "$enable_v4l2" != "no"], [
   ])
 ])
 AS_IF([test "$have_v4l2" = "yes"], [
-  PKG_CHECK_MODULES(LIBV4L2, libv4l2, [
-    AC_DEFINE(HAVE_LIBV4L2, 1, [Define to 1 if libv4l2 is available])
-  ], [
-    AC_MSG_WARN([${LIBV4L2_PKG_ERRORS}.])
-  ])
   AS_IF([test "${enable_pvr}" = "yes"], [
     VLC_ADD_PLUGIN([pvr])
   ])
diff --git a/modules/access/Modules.am b/modules/access/Modules.am
index ce69e25..eee6276 100644
--- a/modules/access/Modules.am
+++ b/modules/access/Modules.am
@@ -162,9 +162,10 @@ libv4l2_plugin_la_SOURCES = \
 	v4l2/demux.c \
 	v4l2/access.c \
 	v4l2/controls.c \
+	v4l2/lib.c \
 	v4l2/v4l2.h
-libv4l2_plugin_la_CFLAGS = $(AM_CFLAGS) $(LIBV4L2_CFLAGS)
-libv4l2_plugin_la_LIBADD = $(AM_LIBADD) $(LIBV4L2_LIBS) $(LIBM)
+libv4l2_plugin_la_CFLAGS = $(AM_CFLAGS)
+libv4l2_plugin_la_LIBADD = $(AM_LIBADD) $(LIBDL) $(LIBM)
 libv4l2_plugin_la_DEPENDENCIES =
 if HAVE_V4L2
 libvlc_LTLIBRARIES += libv4l2_plugin.la
diff --git a/modules/access/v4l2/lib.c b/modules/access/v4l2/lib.c
new file mode 100644
index 0000000..6bd3dfe
--- /dev/null
+++ b/modules/access/v4l2/lib.c
@@ -0,0 +1,89 @@
+/*****************************************************************************
+ * lib.c : libv4l2 run-time
+ *****************************************************************************
+ * Copyright (C) 2012 Rémi Denis-Courmont
+ *
+ * This program 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.
+ *
+ * This program 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 this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <pthread.h>
+#include <dlfcn.h>
+#include <unistd.h>
+#include <sys/ioctl.h>
+#include <sys/mman.h>
+#include "v4l2.h"
+
+static void *v4l2_handle = NULL;
+static int (*v4l2_fd_open_) (int, int);
+int (*v4l2_close) (int);
+int (*v4l2_ioctl) (int, unsigned long int, ...);
+ssize_t (*v4l2_read) (int, void *, size_t);
+void * (*v4l2_mmap) (void *, size_t, int, int, int, int64_t);
+int (*v4l2_munmap) (void *, size_t);
+
+static int fd_open (int fd, int flags)
+{
+    (void) flags;
+    return fd;
+}
+
+static void v4l2_lib_load (void)
+{
+    void *h = dlopen ("libv4l2.so", RTLD_LAZY | RTLD_LOCAL);
+    if (h == NULL)
+        goto fallback;
+
+    v4l2_fd_open_ = dlsym (h, "v4l2_fd_open");
+    v4l2_close = dlsym (h, "v4l2_close");
+    v4l2_ioctl = dlsym (h, "v4l2_ioctl");
+    v4l2_read = dlsym (h, "v4l2_read");
+    v4l2_mmap = dlsym (h, "v4l2_mmap");
+    v4l2_munmap = dlsym (h, "v4l2_munmap");
+
+    if (v4l2_fd_open_ != NULL && v4l2_close != NULL && v4l2_ioctl != NULL
+     && v4l2_read != NULL && v4l2_mmap != NULL && v4l2_munmap != NULL)
+    {
+        v4l2_handle = h;
+        return;
+    }
+
+    dlclose (h);
+fallback:
+    v4l2_fd_open_ = fd_open;
+    v4l2_close = close;
+    v4l2_ioctl = ioctl;
+    v4l2_read = read;
+    v4l2_mmap = mmap;
+    v4l2_munmap = munmap;
+}
+
+__attribute__((destructor))
+static void v4l2_lib_unload (void)
+{
+    if (v4l2_handle != NULL)
+        dlclose (v4l2_handle);
+}
+
+int v4l2_fd_open (int fd, int flags)
+{
+    static pthread_once_t once = PTHREAD_ONCE_INIT;
+
+    pthread_once (&once, v4l2_lib_load);
+    return v4l2_fd_open_ (fd, flags);
+}
diff --git a/modules/access/v4l2/v4l2.h b/modules/access/v4l2/v4l2.h
index 3d8cc1c..705b7f4 100644
--- a/modules/access/v4l2/v4l2.h
+++ b/modules/access/v4l2/v4l2.h
@@ -65,16 +65,13 @@
 # define V4L2_CID_ROTATE (V4L2_CID_BASE+34)
 #endif
 
-#ifdef HAVE_LIBV4L2
-#   include <libv4l2.h>
-#else
-#   define v4l2_close close
-#   define v4l2_dup dup
-#   define v4l2_ioctl ioctl
-#   define v4l2_read read
-#   define v4l2_mmap mmap
-#   define v4l2_munmap munmap
-#endif
+/* libv4l2 functions */
+extern int v4l2_fd_open (int, int);
+extern int (*v4l2_close) (int);
+extern int (*v4l2_ioctl) (int, unsigned long int, ...);
+extern ssize_t (*v4l2_read) (int, void *, size_t);
+extern void * (*v4l2_mmap) (void *, size_t, int, int, int, int64_t);
+extern int (*v4l2_munmap) (void *, size_t);
 
 #define CFG_PREFIX "v4l2-"
 
@@ -105,10 +102,6 @@ struct demux_sys_t
     es_out_id_t *p_es;
 
     vlc_v4l2_ctrl_t *controls;
-
-#ifdef HAVE_LIBV4L2
-    bool b_libv4l2;
-#endif
 };
 
 struct buffer_t
diff --git a/modules/access/v4l2/video.c b/modules/access/v4l2/video.c
index eb577c5..7e24c0d 100644
--- a/modules/access/v4l2/video.c
+++ b/modules/access/v4l2/video.c
@@ -82,12 +82,6 @@
 #define FPS_LONGTEXT N_( "Framerate to capture, if applicable " \
     "(0 for autodetect)." )
 
-#ifdef HAVE_LIBV4L2
-#define LIBV4L2_TEXT N_( "Use libv4l2" )
-#define LIBV4L2_LONGTEXT N_( \
-    "Force usage of the libv4l2 wrapper." )
-#endif
-
 #define CTRL_RESET_TEXT N_( "Reset controls" )
 #define CTRL_RESET_LONGTEXT N_( "Reset controls to defaults." )
 #define BRIGHTNESS_TEXT N_( "Brightness" )
@@ -340,9 +334,7 @@ vlc_module_begin ()
         change_safe()
     add_float( CFG_PREFIX "fps", 0, FPS_TEXT, FPS_LONGTEXT, true )
         change_safe()
-#ifdef HAVE_LIBV4L2
-    add_bool( CFG_PREFIX "use-libv4l2", false, LIBV4L2_TEXT, LIBV4L2_LONGTEXT, true );
-#endif
+    add_obsolete_bool( CFG_PREFIX "use-libv4l2" ) /* since 2.1.0 */
 
     set_section( N_( "Tuner" ), NULL )
     add_integer( CFG_PREFIX "tuner", 0, TUNER_TEXT, TUNER_LONGTEXT,
@@ -807,25 +799,12 @@ int OpenVideo( vlc_object_t *obj, demux_sys_t *sys, bool b_demux )
         return -1;
     }
     free( path );
-#ifdef HAVE_LIBV4L2
-    if( !var_InheritBool( obj, CFG_PREFIX "use-libv4l2" ) )
-    {
-        msg_Dbg( obj, "trying kernel V4L2" );
-        if( InitVideo( obj, fd, sys, b_demux ) == 0 )
-            return fd;
-    }
-    msg_Dbg( obj, "trying library V4L2" );
-    /* Note the v4l2_xxx functions are designed so that if they get passed an
-       unknown fd, the will behave exactly as their regular xxx counterparts,
-       so if v4l2_fd_open fails, we continue as normal (missing the libv4l2
-       custom cam format to normal formats conversion). Chances are big we will
-       still fail then though, as normally v4l2_fd_open only fails if the
-       device is not a v4l2 device. */
+
     int libfd = v4l2_fd_open( fd, 0 );
     if( libfd == -1 )
         goto error;
-    fd = libfd;
-#endif
+    libfd = fd;
+
     if( InitVideo( obj, fd, sys, b_demux ) )
         goto error;
 



More information about the vlc-commits mailing list