Commit ef46dc6c authored by Rémi Denis-Courmont's avatar Rémi Denis-Courmont

v4l2: simplify dynamic loading of libv4l2

parent 362b0da8
......@@ -175,7 +175,7 @@ libv4l2_plugin_la_SOURCES = \
access/v4l2/v4l2.h
libv4l2_plugin_la_CPPFLAGS = $(AM_CPPFLAGS) -I$(srcdir)/access/v4l2
libv4l2_plugin_la_CFLAGS = $(AM_CFLAGS) $(ZVBI_CFLAGS)
libv4l2_plugin_la_LIBADD = $(LIBDL) $(LIBM) $(ZVBI_LIBS) $(LIBPTHREAD)
libv4l2_plugin_la_LIBADD = $(LIBDL) $(LIBM) $(ZVBI_LIBS)
if HAVE_V4L2
access_LTLIBRARIES += libv4l2_plugin.la
endif
......
......@@ -22,7 +22,6 @@
# include "config.h"
#endif
#include <pthread.h>
#include <dlfcn.h>
#include <unistd.h>
#include <sys/ioctl.h>
......@@ -32,48 +31,40 @@
#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_handle = NULL;
int (*v4l2_fd_open) (int, int) = fd_open;
//int (*v4l2_open) (const char *, int, ...) = open;
//int (*v4l2_dup) (const char *, int, ...) = dup;
int (*v4l2_close) (int) = close;
int (*v4l2_ioctl) (int, unsigned long int, ...) = ioctl;
ssize_t (*v4l2_read) (int, void *, size_t) = read;
//ssize_t (*v4l2_write) (int, const void *, size_t) = write;
void * (*v4l2_mmap) (void *, size_t, int, int, int, int64_t) = mmap;
int (*v4l2_munmap) (void *, size_t) = munmap;
__attribute__((constructor))
static void v4l2_lib_load (void)
{
void *h = dlopen ("libv4l2.so.0", RTLD_LAZY | RTLD_LOCAL);
if (h == NULL)
goto fallback;
return;
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");
void *sym;
#define SYM(name) \
sym = dlsym (h, "v4l2_"#name); \
if (sym != NULL) v4l2_##name = sym
if (v4l2_fd_open_ != NULL && v4l2_close != NULL && v4l2_ioctl != NULL
&& v4l2_read != NULL && v4l2_mmap != NULL && v4l2_munmap != NULL)
{
v4l2_handle = h;
return;
}
SYM(fd_open); /*SYM(open); SYM(dup);*/ SYM(close); SYM(ioctl);
SYM(read); /*SYM(write);*/ SYM(mmap); SYM(munmap);
dlclose (h);
fallback:
v4l2_fd_open_ = fd_open;
v4l2_close = close;
v4l2_ioctl = ioctl;
v4l2_read = read;
v4l2_mmap = mmap;
v4l2_munmap = munmap;
v4l2_handle = h;
}
__attribute__((destructor))
......@@ -82,11 +73,3 @@ 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);
}
......@@ -21,7 +21,7 @@
#include <linux/videodev2.h>
/* libv4l2 functions */
extern int v4l2_fd_open (int, int);
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);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment