1From 5fbece9fa1763af70c9e4346af2ac10b0dec0af7 Mon Sep 17 00:00:00 2001
2From: Jeffy Chen <jeffy.chen@rock-chips.com>
3Date: Mon, 1 Jul 2019 10:37:35 +0800
4Subject: [PATCH 03/17] media: capture: linux: Support libv4l2 plugins
5
6Allow using libv4l2 plugins for linux v4l2 capture devices.
7
8Signed-off-by: Jeffy Chen <jeffy.chen@rock-chips.com>
9---
10 media/capture/BUILD.gn                        | 14 +++++
11 .../video/linux/v4l2_capture_device_impl.cc   | 52 ++++++++++++++++++-
12 .../video/linux/v4l2_capture_device_impl.h    | 11 ++++
13 3 files changed, 76 insertions(+), 1 deletion(-)
14
15diff --git a/media/capture/BUILD.gn b/media/capture/BUILD.gn
16index 3f80b62cb..3c6559339 100644
17--- a/media/capture/BUILD.gn
18+++ b/media/capture/BUILD.gn
19@@ -2,6 +2,7 @@
20 # Use of this source code is governed by a BSD-style license that can be
21 # found in the LICENSE file.
22
23+import("//build/buildflag_header.gni")
24 import("//build/config/chromeos/ui_mode.gni")
25 import("//build/config/features.gni")
26 import("//build/config/ui.gni")
27@@ -18,6 +19,14 @@ group("capture") {
28   ]
29 }
30
31+buildflag_header("buildflags") {
32+  header = "buildflags.h"
33+
34+  flags = [
35+    "USE_LIBV4L2=$use_v4lplugin",
36+  ]
37+}
38+
39 component("capture_switches") {
40   defines = [ "CAPTURE_IMPLEMENTATION" ]
41   sources = [
42@@ -266,6 +275,11 @@ component("capture_lib") {
43       "video/linux/video_capture_device_linux.cc",
44       "video/linux/video_capture_device_linux.h",
45     ]
46+    public_deps += [ ":buildflags" ]
47+
48+    if (use_v4lplugin) {
49+      deps += [ "//media/gpu/v4l2:libv4l2_stubs" ]
50+    }
51   }
52
53   if (is_chromeos_ash) {
54diff --git a/media/capture/video/linux/v4l2_capture_device_impl.cc b/media/capture/video/linux/v4l2_capture_device_impl.cc
55index c9040f5de..d05d1179e 100644
56--- a/media/capture/video/linux/v4l2_capture_device_impl.cc
57+++ b/media/capture/video/linux/v4l2_capture_device_impl.cc
58@@ -10,19 +10,61 @@
59 #include <sys/poll.h>
60 #include <unistd.h>
61
62+#if BUILDFLAG(USE_LIBV4L2)
63+// Auto-generated for dlopen libv4l2 libraries
64+#include "media/gpu/v4l2/v4l2_stubs.h"
65+#include "third_party/v4l-utils/lib/include/libv4l2.h"
66+
67+#include "base/files/file_path.h"
68+
69+using media_gpu_v4l2::kModuleV4l2;
70+using media_gpu_v4l2::InitializeStubs;
71+using media_gpu_v4l2::StubPathMap;
72+
73+static const base::FilePath::CharType kV4l2Lib[] =
74+    FILE_PATH_LITERAL("/usr/lib/libv4l2.so");
75+#endif
76+
77 namespace media {
78
79 V4L2CaptureDeviceImpl::~V4L2CaptureDeviceImpl() = default;
80
81+V4L2CaptureDeviceImpl::V4L2CaptureDeviceImpl() {
82+#if BUILDFLAG(USE_LIBV4L2)
83+  StubPathMap paths;
84+  paths[kModuleV4l2].push_back(kV4l2Lib);
85+
86+  has_libv4l2_ = InitializeStubs(paths);
87+#endif
88+}
89+
90 int V4L2CaptureDeviceImpl::open(const char* device_name, int flags) {
91-  return ::open(device_name, flags);
92+  int fd = ::open64(device_name, flags);
93+  if (fd < 0)
94+    return fd;
95+
96+#if BUILDFLAG(USE_LIBV4L2)
97+  use_libv4l2_ = false;
98+  if (has_libv4l2_ && v4l2_fd_open(fd, V4L2_DISABLE_CONVERSION) != -1) {
99+    use_libv4l2_ = true;
100+  }
101+#endif
102+  return fd;
103 }
104
105 int V4L2CaptureDeviceImpl::close(int fd) {
106+#if BUILDFLAG(USE_LIBV4L2)
107+  if (use_libv4l2_)
108+    return v4l2_close(fd);
109+#endif
110   return ::close(fd);
111 }
112
113 int V4L2CaptureDeviceImpl::ioctl(int fd, int request, void* argp) {
114+#if BUILDFLAG(USE_LIBV4L2)
115+  if (use_libv4l2_)
116+    return v4l2_ioctl(fd, request, argp);
117+#endif
118   return ::ioctl(fd, request, argp);
119 }
120
121@@ -32,10 +74,18 @@ void* V4L2CaptureDeviceImpl::mmap(void* start,
122                                   int flags,
123                                   int fd,
124                                   off_t offset) {
125+#if BUILDFLAG(USE_LIBV4L2)
126+  if (use_libv4l2_)
127+    return v4l2_mmap(start, length, prot, flags, fd, offset);
128+#endif
129   return ::mmap(start, length, prot, flags, fd, offset);
130 }
131
132 int V4L2CaptureDeviceImpl::munmap(void* start, size_t length) {
133+#if BUILDFLAG(USE_LIBV4L2)
134+  if (use_libv4l2_)
135+    return v4l2_munmap(start, length);
136+#endif
137   return ::munmap(start, length);
138 }
139
140diff --git a/media/capture/video/linux/v4l2_capture_device_impl.h b/media/capture/video/linux/v4l2_capture_device_impl.h
141index 936c8b093..f96c2d434 100644
142--- a/media/capture/video/linux/v4l2_capture_device_impl.h
143+++ b/media/capture/video/linux/v4l2_capture_device_impl.h
144@@ -8,6 +8,7 @@
145 #include <poll.h>
146 #include <sys/fcntl.h>
147
148+#include "media/capture/buildflags.h"
149 #include "media/capture/capture_export.h"
150 #include "media/capture/video/linux/v4l2_capture_device.h"
151
152@@ -17,6 +18,8 @@ namespace media {
153 // V4L2 APIs.
154 class CAPTURE_EXPORT V4L2CaptureDeviceImpl : public V4L2CaptureDevice {
155  public:
156+  V4L2CaptureDeviceImpl();
157+
158   int open(const char* device_name, int flags) override;
159   int close(int fd) override;
160   int ioctl(int fd, int request, void* argp) override;
161@@ -32,6 +35,14 @@ class CAPTURE_EXPORT V4L2CaptureDeviceImpl : public V4L2CaptureDevice {
162
163  private:
164   ~V4L2CaptureDeviceImpl() override;
165+
166+#if BUILDFLAG(USE_LIBV4L2)
167+  // Has libv4l2.
168+  bool has_libv4l2_;
169+  // Use libv4l2 when operating |fd|.
170+  bool use_libv4l2_;
171+#endif
172+
173 };
174
175 }  // namespace media
176--
1772.20.1
178
179