Skip to content

Commit 57b84b1

Browse files
authored
open v4l2 device with index (#188)
1 parent f643043 commit 57b84b1

File tree

3 files changed

+73
-14
lines changed

3 files changed

+73
-14
lines changed

highgui/src/capture_v4l2.cpp

Lines changed: 71 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ class capture_v4l2_impl
6161
capture_v4l2_impl();
6262
~capture_v4l2_impl();
6363

64-
int open(int width, int height, float fps);
64+
int open(int index, int width, int height, float fps);
6565

6666
int start_streaming();
6767

@@ -150,18 +150,18 @@ static float fit_score(int cap_width, int cap_height, int width, int height)
150150
return iou * 20 + ioo * 80;
151151
}
152152

153-
int capture_v4l2_impl::open(int width, int height, float fps)
153+
int capture_v4l2_impl::open(int index, int width, int height, float fps)
154154
{
155155
int dev_index = -1;
156156

157-
// enumerate /dev/video%d and find capture + streaming
158-
for (int i = 0; i < 64; i++)
157+
// try index first
158+
while (1)
159159
{
160-
sprintf(devpath, "/dev/video%d", i);
160+
sprintf(devpath, "/dev/video%d", index);
161161

162162
fd = ::open(devpath, O_RDWR | O_NONBLOCK, 0);
163163
if (fd < 0)
164-
continue;
164+
break;
165165

166166
// query cap
167167
{
@@ -172,7 +172,7 @@ int capture_v4l2_impl::open(int width, int height, float fps)
172172
{
173173
fprintf(stderr, "%s ioctl VIDIOC_QUERYCAP failed %d %s\n", devpath, errno, strerror(errno));
174174
::close(fd);
175-
continue;
175+
break;
176176
}
177177

178178
fprintf(stderr, " devpath = %s\n", devpath);
@@ -195,21 +195,80 @@ int capture_v4l2_impl::open(int width, int height, float fps)
195195
{
196196
fprintf(stderr, "%s is not V4L2_CAP_VIDEO_CAPTURE or V4L2_CAP_VIDEO_CAPTURE_MPLANE\n", devpath);
197197
::close(fd);
198-
continue;
198+
break;
199199
}
200200

201201
if (!(caps.capabilities & V4L2_CAP_STREAMING))
202202
{
203203
fprintf(stderr, "%s is not V4L2_CAP_STREAMING\n", devpath);
204204
::close(fd);
205-
continue;
205+
break;
206206
}
207207
}
208208

209-
dev_index = i;
209+
dev_index = index;
210210
break;
211211
}
212212

213+
if (dev_index == -1)
214+
{
215+
// enumerate /dev/video%d and find capture + streaming
216+
for (int i = 0; i < 64; i++)
217+
{
218+
sprintf(devpath, "/dev/video%d", i);
219+
220+
fd = ::open(devpath, O_RDWR | O_NONBLOCK, 0);
221+
if (fd < 0)
222+
continue;
223+
224+
// query cap
225+
{
226+
struct v4l2_capability caps;
227+
memset(&caps, 0, sizeof(caps));
228+
229+
if (ioctl(fd, VIDIOC_QUERYCAP, &caps))
230+
{
231+
fprintf(stderr, "%s ioctl VIDIOC_QUERYCAP failed %d %s\n", devpath, errno, strerror(errno));
232+
::close(fd);
233+
continue;
234+
}
235+
236+
fprintf(stderr, " devpath = %s\n", devpath);
237+
fprintf(stderr, " driver = %s\n", caps.driver);
238+
fprintf(stderr, " card = %s\n", caps.card);
239+
fprintf(stderr, " bus_info = %s\n", caps.bus_info);
240+
fprintf(stderr, " version = %x\n", caps.version);
241+
fprintf(stderr, " capabilities = %x\n", caps.capabilities);
242+
fprintf(stderr, " device_caps = %x\n", caps.device_caps);
243+
244+
if (caps.capabilities & V4L2_CAP_VIDEO_CAPTURE)
245+
{
246+
buf_type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
247+
}
248+
else if (caps.capabilities & V4L2_CAP_VIDEO_CAPTURE_MPLANE)
249+
{
250+
buf_type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
251+
}
252+
else
253+
{
254+
fprintf(stderr, "%s is not V4L2_CAP_VIDEO_CAPTURE or V4L2_CAP_VIDEO_CAPTURE_MPLANE\n", devpath);
255+
::close(fd);
256+
continue;
257+
}
258+
259+
if (!(caps.capabilities & V4L2_CAP_STREAMING))
260+
{
261+
fprintf(stderr, "%s is not V4L2_CAP_STREAMING\n", devpath);
262+
::close(fd);
263+
continue;
264+
}
265+
}
266+
267+
dev_index = i;
268+
break;
269+
}
270+
}
271+
213272
if (dev_index == -1)
214273
{
215274
fprintf(stderr, "cannot find v4l device with VIDEO_CAPTURE and STREAMING\n");
@@ -916,9 +975,9 @@ capture_v4l2::~capture_v4l2()
916975
delete d;
917976
}
918977

919-
int capture_v4l2::open(int width, int height, float fps)
978+
int capture_v4l2::open(int index, int width, int height, float fps)
920979
{
921-
return d->open(width, height, fps);
980+
return d->open(index, width, height, fps);
922981
}
923982

924983
int capture_v4l2::get_width() const

highgui/src/capture_v4l2.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ class capture_v4l2
3030
capture_v4l2();
3131
~capture_v4l2();
3232

33-
int open(int width = 640, int height = 480, float fps = 30);
33+
int open(int index, int width = 640, int height = 480, float fps = 30);
3434

3535
int get_width() const;
3636
int get_height() const;

highgui/src/videocapture.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,7 @@ bool VideoCapture::open(int index)
158158
#if defined __linux__
159159
if (capture_v4l2::supported())
160160
{
161-
int ret = d->cap_v4l2.open(d->width, d->height, d->fps);
161+
int ret = d->cap_v4l2.open(index, d->width, d->height, d->fps);
162162
if (ret == 0)
163163
{
164164
d->width = d->cap_v4l2.get_width();

0 commit comments

Comments
 (0)