uvc-gadget: Use macros from tools.h
[uvc-gadget.git] / uvc-gadget.c
1 /*
2  * UVC gadget test application
3  *
4  * Copyright (C) 2010 Ideas on board SPRL <laurent.pinchart@ideasonboard.com>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License along
17  * with this program; if not, write to the Free Software Foundation, Inc.,
18  */
19
20 #include <sys/time.h>
21 #include <sys/ioctl.h>
22 #include <sys/mman.h>
23 #include <sys/types.h>
24 #include <sys/stat.h>
25 #include <sys/select.h>
26
27 #include <unistd.h>
28 #include <fcntl.h>
29 #include <signal.h>
30 #include <stdlib.h>
31 #include <stdio.h>
32 #include <stdint.h>
33 #include <string.h>
34 #include <errno.h>
35
36 #include <linux/usb/ch9.h>
37 #include <linux/usb/g_uvc.h>
38 #include <linux/usb/video.h>
39 #include <linux/videodev2.h>
40
41 #include "events.h"
42 #include "tools.h"
43
44 #define UVC_INTF_CONTROL        0
45 #define UVC_INTF_STREAMING      1
46
47 struct uvc_device
48 {
49         int fd;
50
51         struct uvc_streaming_control probe;
52         struct uvc_streaming_control commit;
53
54         int control;
55
56         unsigned int fcc;
57         unsigned int width;
58         unsigned int height;
59
60         void **mem;
61         unsigned int nbufs;
62         unsigned int bufsize;
63
64         unsigned int bulk;
65         uint8_t color;
66         unsigned int imgsize;
67         void *imgdata;
68
69         struct events events;
70 };
71
72 static struct uvc_device *
73 uvc_open(const char *devname)
74 {
75         struct uvc_device *dev;
76         struct v4l2_capability cap;
77         int ret;
78         int fd;
79
80         fd = open(devname, O_RDWR | O_NONBLOCK);
81         if (fd == -1) {
82                 printf("v4l2 open failed: %s (%d)\n", strerror(errno), errno);
83                 return NULL;
84         }
85
86         printf("open succeeded, file descriptor = %d\n", fd);
87
88         ret = ioctl(fd, VIDIOC_QUERYCAP, &cap);
89         if (ret < 0) {
90                 printf("unable to query device: %s (%d)\n", strerror(errno),
91                         errno);
92                 close(fd);
93                 return NULL;
94         }
95
96         printf("device is %s on bus %s\n", cap.card, cap.bus_info);
97
98         dev = malloc(sizeof *dev);
99         if (dev == NULL) {
100                 close(fd);
101                 return NULL;
102         }
103
104         memset(dev, 0, sizeof *dev);
105         dev->fd = fd;
106
107         events_init(&dev->events);
108
109         return dev;
110 }
111
112 static void
113 uvc_close(struct uvc_device *dev)
114 {
115         close(dev->fd);
116         free(dev->imgdata);
117         free(dev->mem);
118         free(dev);
119 }
120
121 /* ---------------------------------------------------------------------------
122  * Video streaming
123  */
124
125 static void
126 uvc_video_fill_buffer(struct uvc_device *dev, struct v4l2_buffer *buf)
127 {
128         unsigned int bpl;
129         unsigned int i;
130
131         switch (dev->fcc) {
132         case V4L2_PIX_FMT_YUYV:
133                 /* Fill the buffer with video data. */
134                 bpl = dev->width * 2;
135                 for (i = 0; i < dev->height; ++i)
136                         memset(dev->mem[buf->index] + i*bpl, dev->color++, bpl);
137
138                 buf->bytesused = bpl * dev->height;
139                 break;
140
141         case V4L2_PIX_FMT_MJPEG:
142                 memcpy(dev->mem[buf->index], dev->imgdata, dev->imgsize);
143                 buf->bytesused = dev->imgsize;
144                 break;
145         }
146 }
147
148 static void
149 uvc_video_process(void *d)
150 {
151         struct uvc_device *dev = d;
152         struct v4l2_buffer buf;
153         int ret;
154
155         memset(&buf, 0, sizeof buf);
156         buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
157         buf.memory = V4L2_MEMORY_MMAP;
158
159         if ((ret = ioctl(dev->fd, VIDIOC_DQBUF, &buf)) < 0) {
160                 printf("Unable to dequeue buffer: %s (%d).\n", strerror(errno),
161                         errno);
162                 return;
163         }
164
165         uvc_video_fill_buffer(dev, &buf);
166
167         if ((ret = ioctl(dev->fd, VIDIOC_QBUF, &buf)) < 0) {
168                 printf("Unable to requeue buffer: %s (%d).\n", strerror(errno),
169                         errno);
170                 return;
171         }
172 }
173
174 static int
175 uvc_video_reqbufs(struct uvc_device *dev, int nbufs)
176 {
177         struct v4l2_requestbuffers rb;
178         struct v4l2_buffer buf;
179         unsigned int i;
180         int ret;
181
182         for (i = 0; i < dev->nbufs; ++i)
183                 munmap(dev->mem[i], dev->bufsize);
184
185         free(dev->mem);
186         dev->mem = 0;
187         dev->nbufs = 0;
188
189         memset(&rb, 0, sizeof rb);
190         rb.count = nbufs;
191         rb.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
192         rb.memory = V4L2_MEMORY_MMAP;
193
194         ret = ioctl(dev->fd, VIDIOC_REQBUFS, &rb);
195         if (ret < 0) {
196                 printf("Unable to allocate buffers: %s (%d).\n",
197                         strerror(errno), errno);
198                 return ret;
199         }
200
201         printf("%u buffers allocated.\n", rb.count);
202
203         /* Map the buffers. */
204         dev->mem = malloc(rb.count * sizeof dev->mem[0]);
205
206         for (i = 0; i < rb.count; ++i) {
207                 memset(&buf, 0, sizeof buf);
208                 buf.index = i;
209                 buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
210                 buf.memory = V4L2_MEMORY_MMAP;
211                 ret = ioctl(dev->fd, VIDIOC_QUERYBUF, &buf);
212                 if (ret < 0) {
213                         printf("Unable to query buffer %u: %s (%d).\n", i,
214                                 strerror(errno), errno);
215                         return -1;
216                 }
217                 printf("length: %u offset: %u\n", buf.length, buf.m.offset);
218
219                 dev->mem[i] = mmap(0, buf.length, PROT_READ | PROT_WRITE, MAP_SHARED, dev->fd, buf.m.offset);
220                 if (dev->mem[i] == MAP_FAILED) {
221                         printf("Unable to map buffer %u: %s (%d)\n", i,
222                                 strerror(errno), errno);
223                         return -1;
224                 }
225                 printf("Buffer %u mapped at address %p.\n", i, dev->mem[i]);
226         }
227
228         dev->bufsize = buf.length;
229         dev->nbufs = rb.count;
230
231         return 0;
232 }
233
234 static int
235 uvc_video_stream(struct uvc_device *dev, int enable)
236 {
237         struct v4l2_buffer buf;
238         unsigned int i;
239         int type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
240         int ret;
241
242         if (!enable) {
243                 printf("Stopping video stream.\n");
244                 events_unwatch_fd(&dev->events, dev->fd, EVENT_WRITE);
245                 ioctl(dev->fd, VIDIOC_STREAMOFF, &type);
246                 return 0;
247         }
248
249         printf("Starting video stream.\n");
250
251         for (i = 0; i < dev->nbufs; ++i) {
252                 memset(&buf, 0, sizeof buf);
253
254                 buf.index = i;
255                 buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
256                 buf.memory = V4L2_MEMORY_MMAP;
257
258                 uvc_video_fill_buffer(dev, &buf);
259
260                 printf("Queueing buffer %u.\n", i);
261                 if ((ret = ioctl(dev->fd, VIDIOC_QBUF, &buf)) < 0) {
262                         printf("Unable to queue buffer: %s (%d).\n",
263                                 strerror(errno), errno);
264                         break;
265                 }
266         }
267
268         ioctl(dev->fd, VIDIOC_STREAMON, &type);
269         events_watch_fd(&dev->events, dev->fd, EVENT_WRITE,
270                         uvc_video_process, dev);
271         return ret;
272 }
273
274 static int
275 uvc_video_set_format(struct uvc_device *dev)
276 {
277         struct v4l2_format fmt;
278         int ret;
279
280         printf("Setting format to 0x%08x %ux%u\n",
281                 dev->fcc, dev->width, dev->height);
282
283         memset(&fmt, 0, sizeof fmt);
284         fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
285         fmt.fmt.pix.width = dev->width;
286         fmt.fmt.pix.height = dev->height;
287         fmt.fmt.pix.pixelformat = dev->fcc;
288         fmt.fmt.pix.field = V4L2_FIELD_NONE;
289         if (dev->fcc == V4L2_PIX_FMT_MJPEG)
290                 fmt.fmt.pix.sizeimage = dev->imgsize * 1.5;
291
292         if ((ret = ioctl(dev->fd, VIDIOC_S_FMT, &fmt)) < 0)
293                 printf("Unable to set format: %s (%d).\n",
294                         strerror(errno), errno);
295
296         return ret;
297 }
298
299 static int
300 uvc_video_init(struct uvc_device *dev __attribute__((__unused__)))
301 {
302         return 0;
303 }
304
305 /* ---------------------------------------------------------------------------
306  * Request processing
307  */
308
309 struct uvc_frame_info
310 {
311         unsigned int width;
312         unsigned int height;
313         unsigned int intervals[8];
314 };
315
316 struct uvc_format_info
317 {
318         unsigned int fcc;
319         const struct uvc_frame_info *frames;
320 };
321
322 static const struct uvc_frame_info uvc_frames_yuyv[] = {
323         {  640, 360, { 666666, 10000000, 50000000, 0 }, },
324         { 1280, 720, { 50000000, 0 }, },
325         { 0, 0, { 0, }, },
326 };
327
328 static const struct uvc_frame_info uvc_frames_mjpeg[] = {
329         {  640, 360, { 666666, 10000000, 50000000, 0 }, },
330         { 1280, 720, { 50000000, 0 }, },
331         { 0, 0, { 0, }, },
332 };
333
334 static const struct uvc_format_info uvc_formats[] = {
335         { V4L2_PIX_FMT_YUYV, uvc_frames_yuyv },
336         { V4L2_PIX_FMT_MJPEG, uvc_frames_mjpeg },
337 };
338
339 static void
340 uvc_fill_streaming_control(struct uvc_device *dev,
341                            struct uvc_streaming_control *ctrl,
342                            int iframe, int iformat)
343 {
344         const struct uvc_format_info *format;
345         const struct uvc_frame_info *frame;
346         unsigned int nframes;
347
348         if (iformat < 0)
349                 iformat = ARRAY_SIZE(uvc_formats) + iformat;
350         if (iformat < 0 || iformat >= (int)ARRAY_SIZE(uvc_formats))
351                 return;
352         format = &uvc_formats[iformat];
353
354         nframes = 0;
355         while (format->frames[nframes].width != 0)
356                 ++nframes;
357
358         if (iframe < 0)
359                 iframe = nframes + iframe;
360         if (iframe < 0 || iframe >= (int)nframes)
361                 return;
362         frame = &format->frames[iframe];
363
364         memset(ctrl, 0, sizeof *ctrl);
365
366         ctrl->bmHint = 1;
367         ctrl->bFormatIndex = iformat + 1;
368         ctrl->bFrameIndex = iframe + 1;
369         ctrl->dwFrameInterval = frame->intervals[0];
370         switch (format->fcc) {
371         case V4L2_PIX_FMT_YUYV:
372                 ctrl->dwMaxVideoFrameSize = frame->width * frame->height * 2;
373                 break;
374         case V4L2_PIX_FMT_MJPEG:
375                 ctrl->dwMaxVideoFrameSize = dev->imgsize;
376                 break;
377         }
378         ctrl->dwMaxPayloadTransferSize = 512;   /* TODO this should be filled by the driver. */
379         ctrl->bmFramingInfo = 3;
380         ctrl->bPreferedVersion = 1;
381         ctrl->bMaxVersion = 1;
382 }
383
384 static void
385 uvc_events_process_standard(struct uvc_device *dev, struct usb_ctrlrequest *ctrl,
386                             struct uvc_request_data *resp)
387 {
388         printf("standard request\n");
389         (void)dev;
390         (void)ctrl;
391         (void)resp;
392 }
393
394 static void
395 uvc_events_process_control(struct uvc_device *dev, uint8_t req, uint8_t cs,
396                            struct uvc_request_data *resp)
397 {
398         printf("control request (req %02x cs %02x)\n", req, cs);
399         (void)dev;
400         (void)resp;
401 }
402
403 static void
404 uvc_events_process_streaming(struct uvc_device *dev, uint8_t req, uint8_t cs,
405                              struct uvc_request_data *resp)
406 {
407         struct uvc_streaming_control *ctrl;
408
409         printf("streaming request (req %02x cs %02x)\n", req, cs);
410
411         if (cs != UVC_VS_PROBE_CONTROL && cs != UVC_VS_COMMIT_CONTROL)
412                 return;
413
414         ctrl = (struct uvc_streaming_control *)&resp->data;
415         resp->length = sizeof *ctrl;
416
417         switch (req) {
418         case UVC_SET_CUR:
419                 dev->control = cs;
420                 resp->length = 34;
421                 break;
422
423         case UVC_GET_CUR:
424                 if (cs == UVC_VS_PROBE_CONTROL)
425                         memcpy(ctrl, &dev->probe, sizeof *ctrl);
426                 else
427                         memcpy(ctrl, &dev->commit, sizeof *ctrl);
428                 break;
429
430         case UVC_GET_MIN:
431         case UVC_GET_MAX:
432         case UVC_GET_DEF:
433                 uvc_fill_streaming_control(dev, ctrl, req == UVC_GET_MAX ? -1 : 0,
434                                            req == UVC_GET_MAX ? -1 : 0);
435                 break;
436
437         case UVC_GET_RES:
438                 memset(ctrl, 0, sizeof *ctrl);
439                 break;
440
441         case UVC_GET_LEN:
442                 resp->data[0] = 0x00;
443                 resp->data[1] = 0x22;
444                 resp->length = 2;
445                 break;
446
447         case UVC_GET_INFO:
448                 resp->data[0] = 0x03;
449                 resp->length = 1;
450                 break;
451         }
452 }
453
454 static void
455 uvc_events_process_class(struct uvc_device *dev, struct usb_ctrlrequest *ctrl,
456                          struct uvc_request_data *resp)
457 {
458         if ((ctrl->bRequestType & USB_RECIP_MASK) != USB_RECIP_INTERFACE)
459                 return;
460
461         switch (ctrl->wIndex & 0xff) {
462         case UVC_INTF_CONTROL:
463                 uvc_events_process_control(dev, ctrl->bRequest, ctrl->wValue >> 8, resp);
464                 break;
465
466         case UVC_INTF_STREAMING:
467                 uvc_events_process_streaming(dev, ctrl->bRequest, ctrl->wValue >> 8, resp);
468                 break;
469
470         default:
471                 break;
472         }
473 }
474
475 static void
476 uvc_events_process_setup(struct uvc_device *dev, struct usb_ctrlrequest *ctrl,
477                          struct uvc_request_data *resp)
478 {
479         dev->control = 0;
480
481         printf("bRequestType %02x bRequest %02x wValue %04x wIndex %04x "
482                 "wLength %04x\n", ctrl->bRequestType, ctrl->bRequest,
483                 ctrl->wValue, ctrl->wIndex, ctrl->wLength);
484
485         switch (ctrl->bRequestType & USB_TYPE_MASK) {
486         case USB_TYPE_STANDARD:
487                 uvc_events_process_standard(dev, ctrl, resp);
488                 break;
489
490         case USB_TYPE_CLASS:
491                 uvc_events_process_class(dev, ctrl, resp);
492                 break;
493
494         default:
495                 break;
496         }
497 }
498
499 static void
500 uvc_events_process_data(struct uvc_device *dev, struct uvc_request_data *data)
501 {
502         struct uvc_streaming_control *target;
503         struct uvc_streaming_control *ctrl;
504         const struct uvc_format_info *format;
505         const struct uvc_frame_info *frame;
506         const unsigned int *interval;
507         unsigned int iformat, iframe;
508         unsigned int nframes;
509
510         switch (dev->control) {
511         case UVC_VS_PROBE_CONTROL:
512                 printf("setting probe control, length = %d\n", data->length);
513                 target = &dev->probe;
514                 break;
515
516         case UVC_VS_COMMIT_CONTROL:
517                 printf("setting commit control, length = %d\n", data->length);
518                 target = &dev->commit;
519                 break;
520
521         default:
522                 printf("setting unknown control, length = %d\n", data->length);
523                 return;
524         }
525
526         ctrl = (struct uvc_streaming_control *)&data->data;
527         iformat = clamp((unsigned int)ctrl->bFormatIndex, 1U,
528                         (unsigned int)ARRAY_SIZE(uvc_formats));
529         format = &uvc_formats[iformat-1];
530
531         nframes = 0;
532         while (format->frames[nframes].width != 0)
533                 ++nframes;
534
535         iframe = clamp((unsigned int)ctrl->bFrameIndex, 1U, nframes);
536         frame = &format->frames[iframe-1];
537         interval = frame->intervals;
538
539         while (interval[0] < ctrl->dwFrameInterval && interval[1])
540                 ++interval;
541
542         target->bFormatIndex = iformat;
543         target->bFrameIndex = iframe;
544         switch (format->fcc) {
545         case V4L2_PIX_FMT_YUYV:
546                 target->dwMaxVideoFrameSize = frame->width * frame->height * 2;
547                 break;
548         case V4L2_PIX_FMT_MJPEG:
549                 if (dev->imgsize == 0)
550                         printf("WARNING: MJPEG requested and no image loaded.\n");
551                 target->dwMaxVideoFrameSize = dev->imgsize;
552                 break;
553         }
554         target->dwFrameInterval = *interval;
555
556         if (dev->control == UVC_VS_COMMIT_CONTROL) {
557                 dev->fcc = format->fcc;
558                 dev->width = frame->width;
559                 dev->height = frame->height;
560
561                 uvc_video_set_format(dev);
562                 if (dev->bulk)
563                         uvc_video_stream(dev, 1);
564         }
565 }
566
567 static void
568 uvc_events_process(void *d)
569 {
570         struct uvc_device *dev = d;
571         struct v4l2_event v4l2_event;
572         struct uvc_event *uvc_event = (void *)&v4l2_event.u.data;
573         struct uvc_request_data resp;
574         int ret;
575
576         ret = ioctl(dev->fd, VIDIOC_DQEVENT, &v4l2_event);
577         if (ret < 0) {
578                 printf("VIDIOC_DQEVENT failed: %s (%d)\n", strerror(errno),
579                         errno);
580                 return;
581         }
582
583         memset(&resp, 0, sizeof resp);
584         resp.length = -EL2HLT;
585
586         switch (v4l2_event.type) {
587         case UVC_EVENT_CONNECT:
588         case UVC_EVENT_DISCONNECT:
589                 return;
590
591         case UVC_EVENT_SETUP:
592                 uvc_events_process_setup(dev, &uvc_event->req, &resp);
593                 break;
594
595         case UVC_EVENT_DATA:
596                 uvc_events_process_data(dev, &uvc_event->data);
597                 return;
598
599         case UVC_EVENT_STREAMON:
600                 uvc_video_reqbufs(dev, 4);
601                 uvc_video_stream(dev, 1);
602                 return;
603
604         case UVC_EVENT_STREAMOFF:
605                 uvc_video_stream(dev, 0);
606                 uvc_video_reqbufs(dev, 0);
607                 return;
608         }
609
610         ioctl(dev->fd, UVCIOC_SEND_RESPONSE, &resp);
611         if (ret < 0) {
612                 printf("UVCIOC_S_EVENT failed: %s (%d)\n", strerror(errno),
613                         errno);
614                 return;
615         }
616 }
617
618 static void
619 uvc_events_init(struct uvc_device *dev)
620 {
621         struct v4l2_event_subscription sub;
622
623         uvc_fill_streaming_control(dev, &dev->probe, 0, 0);
624         uvc_fill_streaming_control(dev, &dev->commit, 0, 0);
625
626         if (dev->bulk) {
627                 /* FIXME Crude hack, must be negotiated with the driver. */
628                 dev->probe.dwMaxPayloadTransferSize = 16 * 1024;
629                 dev->commit.dwMaxPayloadTransferSize = 16 * 1024;
630         }
631
632
633         memset(&sub, 0, sizeof sub);
634         sub.type = UVC_EVENT_SETUP;
635         ioctl(dev->fd, VIDIOC_SUBSCRIBE_EVENT, &sub);
636         sub.type = UVC_EVENT_DATA;
637         ioctl(dev->fd, VIDIOC_SUBSCRIBE_EVENT, &sub);
638         sub.type = UVC_EVENT_STREAMON;
639         ioctl(dev->fd, VIDIOC_SUBSCRIBE_EVENT, &sub);
640         sub.type = UVC_EVENT_STREAMOFF;
641         ioctl(dev->fd, VIDIOC_SUBSCRIBE_EVENT, &sub);
642 }
643
644 /* ---------------------------------------------------------------------------
645  * main
646  */
647
648 static void image_load(struct uvc_device *dev, const char *img)
649 {
650         int fd = -1;
651
652         if (img == NULL)
653                 return;
654
655         fd = open(img, O_RDONLY);
656         if (fd == -1) {
657                 printf("Unable to open MJPEG image '%s'\n", img);
658                 return;
659         }
660
661         dev->imgsize = lseek(fd, 0, SEEK_END);
662         lseek(fd, 0, SEEK_SET);
663         dev->imgdata = malloc(dev->imgsize);
664         if (dev->imgdata == NULL) {
665                 printf("Unable to allocate memory for MJPEG image\n");
666                 dev->imgsize = 0;
667                 return;
668         }
669
670         read(fd, dev->imgdata, dev->imgsize);
671         close(fd);
672 }
673
674 static void usage(const char *argv0)
675 {
676         fprintf(stderr, "Usage: %s [options]\n", argv0);
677         fprintf(stderr, "Available options are\n");
678         fprintf(stderr, " -b            Use bulk mode\n");
679         fprintf(stderr, " -d device     Video device\n");
680         fprintf(stderr, " -h            Print this help screen and exit\n");
681         fprintf(stderr, " -i image      MJPEG image\n");
682 }
683
684 /* Necesssary for and only used by signal handler. */
685 static struct uvc_device *uvc_device;
686
687 static void sigint_handler(int signal __attribute__((__unused__)))
688 {
689         /* Stop the main loop when the user presses CTRL-C */
690         events_stop(&uvc_device->events);
691 }
692
693 int main(int argc, char *argv[])
694 {
695         char *device = "/dev/video0";
696         struct uvc_device *dev;
697         int bulk_mode = 0;
698         char *mjpeg_image = NULL;
699         int opt;
700
701         while ((opt = getopt(argc, argv, "bd:hi:")) != -1) {
702                 switch (opt) {
703                 case 'b':
704                         bulk_mode = 1;
705                         break;
706
707                 case 'd':
708                         device = optarg;
709                         break;
710
711                 case 'h':
712                         usage(argv[0]);
713                         return 0;
714
715                 case 'i':
716                         mjpeg_image = optarg;
717                         break;
718
719                 default:
720                         fprintf(stderr, "Invalid option '-%c'\n", opt);
721                         usage(argv[0]);
722                         return 1;
723                 }
724         }
725
726         dev = uvc_open(device);
727         if (dev == NULL)
728                 return 1;
729
730         image_load(dev, mjpeg_image);
731
732         dev->bulk = bulk_mode;
733
734         uvc_events_init(dev);
735         uvc_video_init(dev);
736
737         /*
738          * Register a signal handler for SIGINT, received when the user presses
739          * CTRL-C. This will allow the main loop to be interrupted, and resources
740          * to be freed cleanly.
741          */
742         uvc_device = dev;
743         signal(SIGINT, sigint_handler);
744
745         events_watch_fd(&dev->events, dev->fd, EVENT_EXCEPTION,
746                         uvc_events_process, dev);
747
748         /* Main capture loop */
749         events_loop(&dev->events);
750
751         events_cleanup(&dev->events);
752         uvc_close(dev);
753         return 0;
754 }
755