@@ -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
924983int capture_v4l2::get_width () const
0 commit comments