summaryrefslogtreecommitdiff
path: root/src/v4l2/v4l2_compat.cpp
diff options
context:
space:
mode:
authorPaul Elder <paul.elder@ideasonboard.com>2019-12-06 04:14:52 -0500
committerPaul Elder <paul.elder@ideasonboard.com>2020-01-03 19:53:20 -0500
commit0ce8f2390b5280887a2ac179faf2aa01604cb1cc (patch)
treeea8d04e9013b87217bd8266eab5356c03ded19fa /src/v4l2/v4l2_compat.cpp
parenta3b80f3af87198b97f11f0694ff4d7ddde63fc30 (diff)
v4l2: v4l2_compat: Add V4L2 compatibility layer
Add libcamera V4L2 compatibility layer. This initial implementation supports the minimal set of V4L2 operations, which allows getting, setting, and enumerating formats, and streaming frames from a video device. Some data about the wrapped V4L2 video device are hardcoded. Add a build option named 'v4l2' and adjust the build system to selectively compile the V4L2 compatibility layer. For now we match the V4L2 device node to a libcamera camera based on a devnum that a pipeline handler may optionally map to a libcamera camera. Signed-off-by: Paul Elder <paul.elder@ideasonboard.com> Reviewed-by: Jacopo Mondi <jacopo@jmondi.org> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Diffstat (limited to 'src/v4l2/v4l2_compat.cpp')
-rw-r--r--src/v4l2/v4l2_compat.cpp85
1 files changed, 85 insertions, 0 deletions
diff --git a/src/v4l2/v4l2_compat.cpp b/src/v4l2/v4l2_compat.cpp
new file mode 100644
index 00000000..171ebed6
--- /dev/null
+++ b/src/v4l2/v4l2_compat.cpp
@@ -0,0 +1,85 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Copyright (C) 2019, Google Inc.
+ *
+ * v4l2_compat.cpp - V4L2 compatibility layer
+ */
+
+#include "v4l2_compat_manager.h"
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stdarg.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+
+#define LIBCAMERA_PUBLIC __attribute__((visibility("default")))
+
+using namespace libcamera;
+
+#define extract_va_arg(type, arg, last) \
+{ \
+ va_list ap; \
+ va_start(ap, last); \
+ arg = va_arg(ap, type); \
+ va_end(ap); \
+}
+
+extern "C" {
+
+LIBCAMERA_PUBLIC int open(const char *path, int oflag, ...)
+{
+ mode_t mode = 0;
+ if (oflag & O_CREAT || oflag & O_TMPFILE)
+ extract_va_arg(mode_t, mode, oflag);
+
+ return V4L2CompatManager::instance()->openat(AT_FDCWD, path,
+ oflag, mode);
+}
+
+/* _FORTIFY_SOURCE redirects open to __open_2 */
+LIBCAMERA_PUBLIC extern __typeof(open) __open_2 __attribute__ ((alias("open")));
+
+LIBCAMERA_PUBLIC int openat(int dirfd, const char *path, int oflag, ...)
+{
+ mode_t mode = 0;
+ if (oflag & O_CREAT || oflag & O_TMPFILE)
+ extract_va_arg(mode_t, mode, oflag);
+
+ return V4L2CompatManager::instance()->openat(dirfd, path, oflag, mode);
+}
+
+LIBCAMERA_PUBLIC extern __typeof(openat) __openat_2 __attribute__ ((alias("openat")));
+
+LIBCAMERA_PUBLIC int dup(int oldfd)
+{
+ return V4L2CompatManager::instance()->dup(oldfd);
+}
+
+LIBCAMERA_PUBLIC int close(int fd)
+{
+ return V4L2CompatManager::instance()->close(fd);
+}
+
+LIBCAMERA_PUBLIC void *mmap(void *addr, size_t length, int prot, int flags,
+ int fd, off_t offset)
+{
+ return V4L2CompatManager::instance()->mmap(addr, length, prot, flags,
+ fd, offset);
+}
+
+LIBCAMERA_PUBLIC int munmap(void *addr, size_t length)
+{
+ return V4L2CompatManager::instance()->munmap(addr, length);
+}
+
+LIBCAMERA_PUBLIC int ioctl(int fd, unsigned long request, ...)
+{
+ void *arg;
+ extract_va_arg(void *, arg, request);
+
+ return V4L2CompatManager::instance()->ioctl(fd, request, arg);
+}
+
+}