Loading...
Searching...
No Matches
V4L2Loader.hpp
Go to the documentation of this file.
1#pragma once
2
19#include <ossia/detail/dylib_loader.hpp>
20
21#include <fcntl.h>
22#include <sys/ioctl.h>
23#include <sys/types.h>
24#include <unistd.h>
25
26#include <cerrno>
27
28// libv4l2.h is not always installed even where the library is, so the three
29// entry points we use are declared here rather than included.
30extern "C" {
31int v4l2_open(const char* file, int oflag, ...);
32int v4l2_close(int fd);
33int v4l2_dup(int fd);
34int v4l2_ioctl(int fd, unsigned long int request, ...);
35ssize_t v4l2_read(int fd, void* buffer, size_t n);
36ssize_t v4l2_write(int fd, const void* buffer, size_t n);
37void* v4l2_mmap(void* start, size_t length, int prot, int flags, int fd, int64_t offset);
38int v4l2_munmap(void* _start, size_t length);
39}
40
41namespace score::gfx::v4l2
42{
43
45{
46public:
47 decltype(&::v4l2_open) open{};
48 decltype(&::v4l2_close) close{};
49 decltype(&::v4l2_ioctl) ioctl{};
50
51 bool available() const noexcept { return open && close && ioctl; }
52
53 static const Libv4l2& instance()
54 {
55 static const Libv4l2 self;
56 return self;
57 }
58
59private:
60 Libv4l2()
61 : library("libv4l2.so.0")
62 {
63 open = library.symbol<decltype(&::v4l2_open)>("v4l2_open");
64 close = library.symbol<decltype(&::v4l2_close)>("v4l2_close");
65 ioctl = library.symbol<decltype(&::v4l2_ioctl)>("v4l2_ioctl");
66 }
67
68 ossia::dylib_loader library;
69};
70
75inline int retryIoctl(int fd, unsigned long request, void* arg) noexcept
76{
77 const auto& lib = Libv4l2::instance();
78 int r;
79 do
80 {
81 r = lib.available() ? lib.ioctl(fd, request, arg) : ::ioctl(fd, request, arg);
82 } while(r == -1 && errno == EINTR);
83 return r;
84}
85
101inline int openDeviceRaw(const char* path, int flags) noexcept
102{
103 return ::open(path, flags);
104}
105
106inline void closeDeviceRaw(int fd) noexcept
107{
108 ::close(fd);
109}
110
111inline int retryIoctlRaw(int fd, unsigned long request, void* arg) noexcept
112{
113 int r;
114 do
115 {
116 r = ::ioctl(fd, request, arg);
117 } while(r == -1 && errno == EINTR);
118 return r;
119}
120
121inline int openDevice(const char* path, int flags) noexcept
122{
123 const auto& lib = Libv4l2::instance();
124 return lib.available() ? lib.open(path, flags) : ::open(path, flags);
125}
126
127inline void closeDevice(int fd) noexcept
128{
129 const auto& lib = Libv4l2::instance();
130 if(lib.available())
131 lib.close(fd);
132 else
133 ::close(fd);
134}
135
136} // namespace score::gfx::v4l2
int openDeviceRaw(const char *path, int flags) noexcept
Definition V4L2Loader.hpp:101
int retryIoctl(int fd, unsigned long request, void *arg) noexcept
Definition V4L2Loader.hpp:75
Definition V4L2Loader.hpp:45