Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(83)

Side by Side Diff: media/capture/video/linux/video_capture_device_factory_linux.cc

Issue 2169013002: Change class VideoCaptureDevice::Name to struct VideoCaptureDeviceDescriptor (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix build errors Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "media/capture/video/linux/video_capture_device_factory_linux.h" 5 #include "media/capture/video/linux/video_capture_device_factory_linux.h"
6 6
7 #include <errno.h> 7 #include <errno.h>
8 #include <fcntl.h> 8 #include <fcntl.h>
9 #include <stdint.h> 9 #include <stdint.h>
10 #include <sys/ioctl.h> 10 #include <sys/ioctl.h>
11 11
12 #include "base/files/file_enumerator.h" 12 #include "base/files/file_enumerator.h"
13 #include "base/files/scoped_file.h" 13 #include "base/files/scoped_file.h"
14 #include "base/posix/eintr_wrapper.h" 14 #include "base/posix/eintr_wrapper.h"
15 #include "base/strings/stringprintf.h"
15 #include "build/build_config.h" 16 #include "build/build_config.h"
16 17
17 #if defined(OS_OPENBSD) 18 #if defined(OS_OPENBSD)
18 #include <sys/videoio.h> 19 #include <sys/videoio.h>
19 #else 20 #else
20 #include <linux/videodev2.h> 21 #include <linux/videodev2.h>
21 #endif 22 #endif
22 23
23 #if defined(OS_CHROMEOS) 24 #if defined(OS_CHROMEOS)
24 #include "media/capture/video/linux/video_capture_device_chromeos.h" 25 #include "media/capture/video/linux/video_capture_device_chromeos.h"
25 #endif 26 #endif
26 #include "media/capture/video/linux/video_capture_device_linux.h" 27 #include "media/capture/video/linux/video_capture_device_linux.h"
27 28
28 namespace media { 29 namespace media {
29 30
31 // USB VID and PID are both 4 bytes long.
32 static const size_t kVidPidSize = 4;
33
34 // /sys/class/video4linux/video{N}/device is a symlink to the corresponding
35 // USB device info directory.
36 static const char kVidPathTemplate[] =
37 "/sys/class/video4linux/%s/device/../idVendor";
38 static const char kPidPathTemplate[] =
39 "/sys/class/video4linux/%s/device/../idProduct";
40
41 static bool ReadIdFile(const std::string& path, std::string* id) {
42 char id_buf[kVidPidSize];
43 FILE* file = fopen(path.c_str(), "rb");
44 if (!file)
45 return false;
46 const bool success = fread(id_buf, kVidPidSize, 1, file) == 1;
47 fclose(file);
48 if (!success)
49 return false;
50 id->append(id_buf, kVidPidSize);
51 return true;
52 }
53
30 static bool HasUsableFormats(int fd, uint32_t capabilities) { 54 static bool HasUsableFormats(int fd, uint32_t capabilities) {
31 if (!(capabilities & V4L2_CAP_VIDEO_CAPTURE)) 55 if (!(capabilities & V4L2_CAP_VIDEO_CAPTURE))
32 return false; 56 return false;
33 57
34 const std::list<uint32_t>& usable_fourccs = 58 const std::list<uint32_t>& usable_fourccs =
35 VideoCaptureDeviceLinux::GetListOfUsableFourCCs(false); 59 VideoCaptureDeviceLinux::GetListOfUsableFourCCs(false);
36 v4l2_fmtdesc fmtdesc = {}; 60 v4l2_fmtdesc fmtdesc = {};
37 fmtdesc.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 61 fmtdesc.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
38 for (; HANDLE_EINTR(ioctl(fd, VIDIOC_ENUM_FMT, &fmtdesc)) == 0; 62 for (; HANDLE_EINTR(ioctl(fd, VIDIOC_ENUM_FMT, &fmtdesc)) == 0;
39 ++fmtdesc.index) { 63 ++fmtdesc.index) {
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
121 } 145 }
122 146
123 VideoCaptureDeviceFactoryLinux::VideoCaptureDeviceFactoryLinux( 147 VideoCaptureDeviceFactoryLinux::VideoCaptureDeviceFactoryLinux(
124 scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner) 148 scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner)
125 : ui_task_runner_(ui_task_runner) { 149 : ui_task_runner_(ui_task_runner) {
126 } 150 }
127 151
128 VideoCaptureDeviceFactoryLinux::~VideoCaptureDeviceFactoryLinux() { 152 VideoCaptureDeviceFactoryLinux::~VideoCaptureDeviceFactoryLinux() {
129 } 153 }
130 154
131 std::unique_ptr<VideoCaptureDevice> VideoCaptureDeviceFactoryLinux::Create( 155 std::unique_ptr<VideoCaptureDevice>
132 const VideoCaptureDevice::Name& device_name) { 156 VideoCaptureDeviceFactoryLinux::CreateDevice(
157 const VideoCaptureDeviceDescriptor& device_descriptor) {
133 DCHECK(thread_checker_.CalledOnValidThread()); 158 DCHECK(thread_checker_.CalledOnValidThread());
134 #if defined(OS_CHROMEOS) 159 #if defined(OS_CHROMEOS)
135 VideoCaptureDeviceChromeOS* self = 160 VideoCaptureDeviceChromeOS* self =
136 new VideoCaptureDeviceChromeOS(ui_task_runner_, device_name); 161 new VideoCaptureDeviceChromeOS(ui_task_runner_, device_descriptor);
137 #else 162 #else
138 VideoCaptureDeviceLinux* self = new VideoCaptureDeviceLinux(device_name); 163 VideoCaptureDeviceLinux* self =
164 new VideoCaptureDeviceLinux(device_descriptor);
139 #endif 165 #endif
140 if (!self) 166 if (!self)
141 return std::unique_ptr<VideoCaptureDevice>(); 167 return std::unique_ptr<VideoCaptureDevice>();
142 // Test opening the device driver. This is to make sure it is available. 168 // Test opening the device driver. This is to make sure it is available.
143 // We will reopen it again in our worker thread when someone 169 // We will reopen it again in our worker thread when someone
144 // allocates the camera. 170 // allocates the camera.
145 base::ScopedFD fd(HANDLE_EINTR(open(device_name.id().c_str(), O_RDONLY))); 171 base::ScopedFD fd(
172 HANDLE_EINTR(open(device_descriptor.device_id.c_str(), O_RDONLY)));
146 if (!fd.is_valid()) { 173 if (!fd.is_valid()) {
147 DLOG(ERROR) << "Cannot open device"; 174 DLOG(ERROR) << "Cannot open device";
148 delete self; 175 delete self;
149 return std::unique_ptr<VideoCaptureDevice>(); 176 return std::unique_ptr<VideoCaptureDevice>();
150 } 177 }
151 178
152 return std::unique_ptr<VideoCaptureDevice>(self); 179 return std::unique_ptr<VideoCaptureDevice>(self);
153 } 180 }
154 181
155 void VideoCaptureDeviceFactoryLinux::GetDeviceNames( 182 void VideoCaptureDeviceFactoryLinux::GetDeviceDescriptors(
156 VideoCaptureDevice::Names* const device_names) { 183 VideoCaptureDeviceDescriptors* device_descriptors) {
157 DCHECK(thread_checker_.CalledOnValidThread()); 184 DCHECK(thread_checker_.CalledOnValidThread());
158 DCHECK(device_names->empty()); 185 DCHECK(device_descriptors->empty());
159 const base::FilePath path("/dev/"); 186 const base::FilePath path("/dev/");
160 base::FileEnumerator enumerator(path, false, base::FileEnumerator::FILES, 187 base::FileEnumerator enumerator(path, false, base::FileEnumerator::FILES,
161 "video*"); 188 "video*");
162 189
163 while (!enumerator.Next().empty()) { 190 while (!enumerator.Next().empty()) {
164 const base::FileEnumerator::FileInfo info = enumerator.GetInfo(); 191 const base::FileEnumerator::FileInfo info = enumerator.GetInfo();
165 const std::string unique_id = path.value() + info.GetName().value(); 192 const std::string unique_id = path.value() + info.GetName().value();
166 const base::ScopedFD fd(HANDLE_EINTR(open(unique_id.c_str(), O_RDONLY))); 193 const base::ScopedFD fd(HANDLE_EINTR(open(unique_id.c_str(), O_RDONLY)));
167 if (!fd.is_valid()) { 194 if (!fd.is_valid()) {
168 DLOG(ERROR) << "Couldn't open " << info.GetName().value(); 195 DLOG(ERROR) << "Couldn't open " << info.GetName().value();
169 continue; 196 continue;
170 } 197 }
171 // Test if this is a V4L2 capture device and if it has at least one 198 // Test if this is a V4L2 capture device and if it has at least one
172 // supported capture format. Devices that have capture and output 199 // supported capture format. Devices that have capture and output
173 // capabilities at the same time are memory-to-memory and are skipped, see 200 // capabilities at the same time are memory-to-memory and are skipped, see
174 // http://crbug.com/139356. 201 // http://crbug.com/139356.
175 v4l2_capability cap; 202 v4l2_capability cap;
176 if ((HANDLE_EINTR(ioctl(fd.get(), VIDIOC_QUERYCAP, &cap)) == 0) && 203 if ((HANDLE_EINTR(ioctl(fd.get(), VIDIOC_QUERYCAP, &cap)) == 0) &&
177 (cap.capabilities & V4L2_CAP_VIDEO_CAPTURE && 204 (cap.capabilities & V4L2_CAP_VIDEO_CAPTURE &&
178 !(cap.capabilities & V4L2_CAP_VIDEO_OUTPUT)) && 205 !(cap.capabilities & V4L2_CAP_VIDEO_OUTPUT)) &&
179 HasUsableFormats(fd.get(), cap.capabilities)) { 206 HasUsableFormats(fd.get(), cap.capabilities)) {
180 device_names->push_back(VideoCaptureDevice::Name( 207 const std::string model_id = GetDeviceModelId(unique_id);
181 reinterpret_cast<char*>(cap.card), unique_id, 208 device_descriptors->emplace_back(
182 VideoCaptureDevice::Name::V4L2_SINGLE_PLANE)); 209 reinterpret_cast<char*>(cap.card), unique_id, model_id,
210 VideoCaptureApi::LINUX_V4L2_SINGLE_PLANE);
183 } 211 }
184 } 212 }
185 } 213 }
186 214
187 void VideoCaptureDeviceFactoryLinux::GetDeviceSupportedFormats( 215 void VideoCaptureDeviceFactoryLinux::GetSupportedFormats(
188 const VideoCaptureDevice::Name& device, 216 const VideoCaptureDeviceDescriptor& device,
189 VideoCaptureFormats* supported_formats) { 217 VideoCaptureFormats* supported_formats) {
190 DCHECK(thread_checker_.CalledOnValidThread()); 218 DCHECK(thread_checker_.CalledOnValidThread());
191 if (device.id().empty()) 219 if (device.device_id.empty())
192 return; 220 return;
193 base::ScopedFD fd(HANDLE_EINTR(open(device.id().c_str(), O_RDONLY))); 221 base::ScopedFD fd(HANDLE_EINTR(open(device.device_id.c_str(), O_RDONLY)));
194 if (!fd.is_valid()) // Failed to open this device. 222 if (!fd.is_valid()) // Failed to open this device.
195 return; 223 return;
196 supported_formats->clear(); 224 supported_formats->clear();
197 225
198 DCHECK_NE(device.capture_api_type(), 226 DCHECK_NE(device.capture_api, VideoCaptureApi::UNKNOWN);
199 VideoCaptureDevice::Name::API_TYPE_UNKNOWN);
200 GetSupportedFormatsForV4L2BufferType(fd.get(), supported_formats); 227 GetSupportedFormatsForV4L2BufferType(fd.get(), supported_formats);
201 } 228 }
202 229
230 std::string VideoCaptureDeviceFactoryLinux::GetDeviceModelId(
231 const std::string& device_id) {
232 // |unique_id| is of the form "/dev/video2". |file_name| is "video2".
233 const std::string dev_dir = "/dev/";
234 DCHECK_EQ(0, device_id.compare(0, dev_dir.length(), dev_dir));
235 const std::string file_name =
236 device_id.substr(dev_dir.length(), device_id.length());
237
238 const std::string vidPath =
239 base::StringPrintf(kVidPathTemplate, file_name.c_str());
240 const std::string pidPath =
241 base::StringPrintf(kPidPathTemplate, file_name.c_str());
242
243 std::string usb_id;
244 if (!ReadIdFile(vidPath, &usb_id))
245 return "";
246 usb_id.append(":");
247 if (!ReadIdFile(pidPath, &usb_id))
248 return "";
249
250 return usb_id;
251 }
252
203 // static 253 // static
204 VideoCaptureDeviceFactory* 254 VideoCaptureDeviceFactory*
205 VideoCaptureDeviceFactory::CreateVideoCaptureDeviceFactory( 255 VideoCaptureDeviceFactory::CreateVideoCaptureDeviceFactory(
206 scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner) { 256 scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner) {
207 return new VideoCaptureDeviceFactoryLinux(ui_task_runner); 257 return new VideoCaptureDeviceFactoryLinux(ui_task_runner);
208 } 258 }
209 259
210 } // namespace media 260 } // namespace media
OLDNEW
« no previous file with comments | « media/capture/video/linux/video_capture_device_factory_linux.h ('k') | media/capture/video/linux/video_capture_device_linux.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698