Add buffer error flag to information printed after VIDIOC_DQBUF
[omap4-v4l2-camera:yavta.git] / yavta.c
1 /*
2  * yavta --  Yet Another V4L2 Test Application
3  *
4  * Copyright (C) 2005-2010 Laurent Pinchart <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 <stdio.h>
21 #include <string.h>
22 #include <fcntl.h>
23 #include <unistd.h>
24 #include <stdint.h>
25 #include <stdlib.h>
26 #include <errno.h>
27 #include <getopt.h>
28 #include <sys/ioctl.h>
29 #include <sys/mman.h>
30 #include <sys/select.h>
31 #include <sys/time.h>
32
33 #include <linux/videodev2.h>
34
35 #ifndef V4L2_BUF_FLAG_ERROR
36 #define V4L2_BUF_FLAG_ERROR     0x0040
37 #endif
38
39 #define ARRAY_SIZE(a)   (sizeof(a)/sizeof((a)[0]))
40
41 struct device
42 {
43         int fd;
44
45         enum v4l2_buf_type type;
46         enum v4l2_memory memtype;
47         unsigned int nbufs;
48         unsigned int bufsize;
49         void **mem;
50
51         unsigned int width;
52         unsigned int height;
53         unsigned int bytesperline;
54         unsigned int imagesize;
55
56         void *pattern;
57 };
58
59 static const char *v4l2_buf_type_name(enum v4l2_buf_type type)
60 {
61         static struct {
62                 enum v4l2_buf_type type;
63                 const char *name;
64         } names[] = {
65                 { V4L2_BUF_TYPE_VIDEO_CAPTURE, "Video capture" },
66                 { V4L2_BUF_TYPE_VIDEO_OUTPUT, "Video output" },
67                 { V4L2_BUF_TYPE_VIDEO_OVERLAY, "Video overlay" },
68         };
69
70         unsigned int i;
71
72         for (i = 0; i < ARRAY_SIZE(names); ++i) {
73                 if (names[i].type == type)
74                         return names[i].name;
75         }
76
77         if (type & V4L2_BUF_TYPE_PRIVATE)
78                 return "Private";
79         else
80                 return "Unknown";
81 }
82
83 static const char *v4l2_fourcc_name(unsigned int fourcc)
84 {
85         static char name[5];
86         unsigned int i;
87
88         for (i = 0; i < 4; ++i) {
89                 name[i] = fourcc & 0xff;
90                 fourcc >>= 8;
91         }
92
93         name[4] = '\0';
94         return name;
95 }
96
97 static int video_open(struct device *dev, const char *devname, int no_query)
98 {
99         struct v4l2_capability cap;
100         int ret;
101
102         memset(dev, 0, sizeof *dev);
103         dev->fd = -1;
104         dev->memtype = V4L2_MEMORY_MMAP;
105         dev->mem = NULL;
106
107         dev->fd = open(devname, O_RDWR);
108         if (dev->fd < 0) {
109                 printf("Error opening device %s: %d.\n", devname, errno);
110                 return dev->fd;
111         }
112
113         if (!no_query) {
114                 memset(&cap, 0, sizeof cap);
115                 ret = ioctl(dev->fd, VIDIOC_QUERYCAP, &cap);
116                 if (ret < 0) {
117                         printf("Error opening device %s: unable to query "
118                                 "device.\n", devname);
119                         close(dev->fd);
120                         return ret;
121                 }
122
123                 if (cap.capabilities & V4L2_CAP_VIDEO_CAPTURE)
124                         dev->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
125                 else if (cap.capabilities & V4L2_CAP_VIDEO_OUTPUT)
126                         dev->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
127                 else {
128                         printf("Error opening device %s: neither video capture "
129                                 "nor video output supported.\n", devname);
130                         close(dev->fd);
131                         return -EINVAL;
132                 }
133
134                 printf("Device %s opened: %s (%s).\n", devname, cap.card, cap.bus_info);
135         } else {
136                 dev->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
137                 printf("Device %s opened.\n", devname);
138         }
139
140         return 0;
141 }
142
143 static void video_close(struct device *dev)
144 {
145         free(dev->pattern);
146         free(dev->mem);
147         close(dev->fd);
148 }
149
150 static void uvc_get_control(struct device *dev, unsigned int id)
151 {
152         struct v4l2_control ctrl;
153         int ret;
154
155         ctrl.id = id;
156
157         ret = ioctl(dev->fd, VIDIOC_G_CTRL, &ctrl);
158         if (ret < 0) {
159                 printf("unable to get control: %s (%d).\n",
160                         strerror(errno), errno);
161                 return;
162         }
163
164         printf("Control 0x%08x value %u\n", id, ctrl.value);
165 }
166
167 static void uvc_set_control(struct device *dev, unsigned int id, int value)
168 {
169         struct v4l2_control ctrl;
170         int ret;
171
172         ctrl.id = id;
173         ctrl.value = value;
174
175         ret = ioctl(dev->fd, VIDIOC_S_CTRL, &ctrl);
176         if (ret < 0) {
177                 printf("unable to set control: %s (%d).\n",
178                         strerror(errno), errno);
179                 return;
180         }
181
182         printf("Control 0x%08x set to %u, is %u\n", id, value,
183                 ctrl.value);
184 }
185
186 static int video_get_format(struct device *dev)
187 {
188         struct v4l2_format fmt;
189         int ret;
190
191         memset(&fmt, 0, sizeof fmt);
192         fmt.type = dev->type;
193
194         ret = ioctl(dev->fd, VIDIOC_G_FMT, &fmt);
195         if (ret < 0) {
196                 printf("Unable to get format: %s (%d).\n", strerror(errno),
197                         errno);
198                 return ret;
199         }
200
201         dev->width = fmt.fmt.pix.width;
202         dev->height = fmt.fmt.pix.height;
203         dev->bytesperline = fmt.fmt.pix.bytesperline;
204         dev->imagesize = fmt.fmt.pix.bytesperline ? fmt.fmt.pix.sizeimage : 0;
205
206         printf("Video format: %c%c%c%c (%08x) %ux%u\n",
207                 (fmt.fmt.pix.pixelformat >> 0) & 0xff,
208                 (fmt.fmt.pix.pixelformat >> 8) & 0xff,
209                 (fmt.fmt.pix.pixelformat >> 16) & 0xff,
210                 (fmt.fmt.pix.pixelformat >> 24) & 0xff,
211                 fmt.fmt.pix.pixelformat,
212                 fmt.fmt.pix.width, fmt.fmt.pix.height);
213         return 0;
214 }
215
216 static int video_set_format(struct device *dev, unsigned int w, unsigned int h, unsigned int format)
217 {
218         struct v4l2_format fmt;
219         int ret;
220
221         memset(&fmt, 0, sizeof fmt);
222         fmt.type = dev->type;
223         fmt.fmt.pix.width = w;
224         fmt.fmt.pix.height = h;
225         fmt.fmt.pix.pixelformat = format;
226         fmt.fmt.pix.field = V4L2_FIELD_ANY;
227
228         ret = ioctl(dev->fd, VIDIOC_S_FMT, &fmt);
229         if (ret < 0) {
230                 printf("Unable to set format: %s (%d).\n", strerror(errno),
231                         errno);
232                 return ret;
233         }
234
235         printf("Video format set: width: %u height: %u buffer size: %u\n",
236                 fmt.fmt.pix.width, fmt.fmt.pix.height, fmt.fmt.pix.sizeimage);
237         return 0;
238 }
239
240 static int video_set_framerate(struct device *dev, struct v4l2_fract *time_per_frame)
241 {
242         struct v4l2_streamparm parm;
243         int ret;
244
245         memset(&parm, 0, sizeof parm);
246         parm.type = dev->type;
247
248         ret = ioctl(dev->fd, VIDIOC_G_PARM, &parm);
249         if (ret < 0) {
250                 printf("Unable to get frame rate: %d.\n", errno);
251                 return ret;
252         }
253
254         printf("Current frame rate: %u/%u\n",
255                 parm.parm.capture.timeperframe.numerator,
256                 parm.parm.capture.timeperframe.denominator);
257
258         printf("Setting frame rate to: %u/%u\n",
259                 time_per_frame->numerator,
260                 time_per_frame->denominator);
261
262         parm.parm.capture.timeperframe.numerator = time_per_frame->numerator;
263         parm.parm.capture.timeperframe.denominator = time_per_frame->denominator;
264
265         ret = ioctl(dev->fd, VIDIOC_S_PARM, &parm);
266         if (ret < 0) {
267                 printf("Unable to set frame rate: %d.\n", errno);
268                 return ret;
269         }
270
271         ret = ioctl(dev->fd, VIDIOC_G_PARM, &parm);
272         if (ret < 0) {
273                 printf("Unable to get frame rate: %d.\n", errno);
274                 return ret;
275         }
276
277         printf("Frame rate set: %u/%u\n",
278                 parm.parm.capture.timeperframe.numerator,
279                 parm.parm.capture.timeperframe.denominator);
280         return 0;
281 }
282
283 static int video_alloc_buffers(struct device *dev, int nbufs, unsigned int offset)
284 {
285         struct v4l2_requestbuffers rb;
286         struct v4l2_buffer buf;
287         int page_size;
288         void **bufmem;
289         unsigned int i;
290         int ret;
291
292         memset(&rb, 0, sizeof rb);
293         rb.count = nbufs;
294         rb.type = dev->type;
295         rb.memory = dev->memtype;
296
297         ret = ioctl(dev->fd, VIDIOC_REQBUFS, &rb);
298         if (ret < 0) {
299                 printf("Unable to request buffers: %d.\n", errno);
300                 return ret;
301         }
302
303         printf("%u buffers requested.\n", rb.count);
304
305         bufmem = malloc(rb.count * sizeof bufmem[0]);
306         if (bufmem == NULL)
307                 return -ENOMEM;
308
309         page_size = getpagesize();
310
311         /* Map the buffers. */
312         for (i = 0; i < rb.count; ++i) {
313                 memset(&buf, 0, sizeof buf);
314                 buf.index = i;
315                 buf.type = dev->type;
316                 buf.memory = dev->memtype;
317                 ret = ioctl(dev->fd, VIDIOC_QUERYBUF, &buf);
318                 if (ret < 0) {
319                         printf("Unable to query buffer %u (%d).\n", i, errno);
320                         return ret;
321                 }
322                 printf("length: %u offset: %u\n", buf.length, buf.m.offset);
323
324                 switch (dev->memtype) {
325                 case V4L2_MEMORY_MMAP:
326                         bufmem[i] = mmap(0, buf.length, PROT_READ | PROT_WRITE, MAP_SHARED, dev->fd, buf.m.offset);
327                         if (bufmem[i] == MAP_FAILED) {
328                                 printf("Unable to map buffer %u (%d)\n", i, errno);
329                                 return ret;
330                         }
331                         printf("Buffer %u mapped at address %p.\n", i, bufmem[i]);
332                         break;
333
334                 case V4L2_MEMORY_USERPTR:
335                         ret = posix_memalign(&bufmem[i], page_size, buf.length + offset);
336                         if (ret < 0) {
337                                 printf("Unable to allocate buffer %u (%d)\n", i, ret);
338                                 return -ENOMEM;
339                         }
340                         bufmem[i] += offset;
341                         printf("Buffer %u allocated at address %p.\n", i, bufmem[i]);
342                         break;
343
344                 default:
345                         break;
346                 }
347         }
348
349         dev->mem = bufmem;
350         dev->nbufs = rb.count;
351         dev->bufsize = buf.length;
352         return 0;
353 }
354
355 static int video_free_buffers(struct device *dev)
356 {
357         struct v4l2_requestbuffers rb;
358         unsigned int i;
359         int ret;
360
361         if (dev->nbufs == 0)
362                 return 0;
363
364         if (dev->memtype == V4L2_MEMORY_MMAP) {
365                 for (i = 0; i < dev->nbufs; ++i) {
366                         ret = munmap(dev->mem[i], dev->bufsize);
367                         if (ret < 0) {
368                                 printf("Unable to unmap buffer %u (%d)\n", i, errno);
369                                 return ret;
370                         }
371                 }
372         }
373
374         memset(&rb, 0, sizeof rb);
375         rb.count = 0;
376         rb.type = dev->type;
377         rb.memory = dev->memtype;
378
379         ret = ioctl(dev->fd, VIDIOC_REQBUFS, &rb);
380         if (ret < 0) {
381                 printf("Unable to release buffers: %d.\n", errno);
382                 return ret;
383         }
384
385         printf("%u buffers released.\n", dev->nbufs);
386
387         free(dev->mem);
388         dev->nbufs = 0;
389         dev->mem = NULL;
390
391         return 0;
392 }
393
394 static int video_queue_buffer(struct device *dev, int index)
395 {
396         struct v4l2_buffer buf;
397         int ret;
398
399         memset(&buf, 0, sizeof buf);
400         buf.index = index;
401         buf.type = dev->type;
402         buf.memory = dev->memtype;
403         buf.length = dev->bufsize;
404         if (dev->memtype == V4L2_MEMORY_USERPTR)
405                 buf.m.userptr = (unsigned long)dev->mem[index];
406
407         if (dev->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) {
408                 buf.bytesused = buf.length;
409                 memcpy(dev->mem[buf.index], dev->pattern, buf.bytesused);
410         }
411
412         ret = ioctl(dev->fd, VIDIOC_QBUF, &buf);
413         if (ret < 0)
414                 printf("Unable to queue buffer (%d).\n", errno);
415
416         return ret;
417 }
418
419 static int video_enable(struct device *dev, int enable)
420 {
421         int type = dev->type;
422         int ret;
423
424         ret = ioctl(dev->fd, enable ? VIDIOC_STREAMON : VIDIOC_STREAMOFF, &type);
425         if (ret < 0) {
426                 printf("Unable to %s streaming: %d.\n", enable ? "start" : "stop",
427                         errno);
428                 return ret;
429         }
430
431         return 0;
432 }
433
434 static void video_query_menu(struct device *dev, unsigned int id)
435 {
436         struct v4l2_querymenu menu;
437         int ret;
438
439         menu.index = 0;
440         while (1) {
441                 menu.id = id;
442                 ret = ioctl(dev->fd, VIDIOC_QUERYMENU, &menu);
443                 if (ret < 0)
444                         break;
445
446                 printf("  %u: %.32s\n", menu.index, menu.name);
447                 menu.index++;
448         };
449 }
450
451 static void video_list_controls(struct device *dev)
452 {
453         struct v4l2_queryctrl query;
454         struct v4l2_control ctrl;
455         unsigned int nctrls = 0;
456         char value[12];
457         int ret;
458
459 #ifndef V4L2_CTRL_FLAG_NEXT_CTRL
460         unsigned int i;
461
462         for (i = V4L2_CID_BASE; i <= V4L2_CID_LASTP1; ++i) {
463                 query.id = i;
464 #else
465         query.id = 0;
466         while (1) {
467                 query.id |= V4L2_CTRL_FLAG_NEXT_CTRL;
468 #endif
469                 ret = ioctl(dev->fd, VIDIOC_QUERYCTRL, &query);
470                 if (ret < 0)
471                         break;
472
473                 if (query.flags & V4L2_CTRL_FLAG_DISABLED)
474                         continue;
475
476                 ctrl.id = query.id;
477                 ret = ioctl(dev->fd, VIDIOC_G_CTRL, &ctrl);
478                 if (ret < 0)
479                         strcpy(value, "n/a");
480                 else
481                         sprintf(value, "%d", ctrl.value);
482
483                 printf("control 0x%08x %s min %d max %d step %d default %d current %s.\n",
484                         query.id, query.name, query.minimum, query.maximum,
485                         query.step, query.default_value, value);
486
487                 if (query.type == V4L2_CTRL_TYPE_MENU)
488                         video_query_menu(dev, query.id);
489
490                 nctrls++;
491         }
492
493         if (nctrls)
494                 printf("%u control%s found.\n", nctrls, nctrls > 1 ? "s" : "");
495         else
496                 printf("No control found.\n");
497 }
498
499 static void video_enum_frame_intervals(struct device *dev, __u32 pixelformat,
500         unsigned int width, unsigned int height)
501 {
502         struct v4l2_frmivalenum ival;
503         unsigned int i;
504         int ret;
505
506         for (i = 0; ; ++i) {
507                 memset(&ival, 0, sizeof ival);
508                 ival.index = i;
509                 ival.pixel_format = pixelformat;
510                 ival.width = width;
511                 ival.height = height;
512                 ret = ioctl(dev->fd, VIDIOC_ENUM_FRAMEINTERVALS, &ival);
513                 if (ret < 0)
514                         break;
515
516                 if (i != ival.index)
517                         printf("Warning: driver returned wrong ival index "
518                                 "%u.\n", ival.index);
519                 if (pixelformat != ival.pixel_format)
520                         printf("Warning: driver returned wrong ival pixel "
521                                 "format %08x.\n", ival.pixel_format);
522                 if (width != ival.width)
523                         printf("Warning: driver returned wrong ival width "
524                                 "%u.\n", ival.width);
525                 if (height != ival.height)
526                         printf("Warning: driver returned wrong ival height "
527                                 "%u.\n", ival.height);
528
529                 if (i != 0)
530                         printf(", ");
531
532                 switch (ival.type) {
533                 case V4L2_FRMIVAL_TYPE_DISCRETE:
534                         printf("%u/%u",
535                                 ival.discrete.numerator,
536                                 ival.discrete.denominator);
537                         break;
538
539                 case V4L2_FRMIVAL_TYPE_CONTINUOUS:
540                         printf("%u/%u - %u/%u",
541                                 ival.stepwise.min.numerator,
542                                 ival.stepwise.min.denominator,
543                                 ival.stepwise.max.numerator,
544                                 ival.stepwise.max.denominator);
545                         return;
546
547                 case V4L2_FRMIVAL_TYPE_STEPWISE:
548                         printf("%u/%u - %u/%u (by %u/%u)",
549                                 ival.stepwise.min.numerator,
550                                 ival.stepwise.min.denominator,
551                                 ival.stepwise.max.numerator,
552                                 ival.stepwise.max.denominator,
553                                 ival.stepwise.step.numerator,
554                                 ival.stepwise.step.denominator);
555                         return;
556
557                 default:
558                         break;
559                 }
560         }
561 }
562
563 static void video_enum_frame_sizes(struct device *dev, __u32 pixelformat)
564 {
565         struct v4l2_frmsizeenum frame;
566         unsigned int i;
567         int ret;
568
569         for (i = 0; ; ++i) {
570                 memset(&frame, 0, sizeof frame);
571                 frame.index = i;
572                 frame.pixel_format = pixelformat;
573                 ret = ioctl(dev->fd, VIDIOC_ENUM_FRAMESIZES, &frame);
574                 if (ret < 0)
575                         break;
576
577                 if (i != frame.index)
578                         printf("Warning: driver returned wrong frame index "
579                                 "%u.\n", frame.index);
580                 if (pixelformat != frame.pixel_format)
581                         printf("Warning: driver returned wrong frame pixel "
582                                 "format %08x.\n", frame.pixel_format);
583
584                 switch (frame.type) {
585                 case V4L2_FRMSIZE_TYPE_DISCRETE:
586                         printf("\tFrame size: %ux%u (", frame.discrete.width,
587                                 frame.discrete.height);
588                         video_enum_frame_intervals(dev, frame.pixel_format,
589                                 frame.discrete.width, frame.discrete.height);
590                         printf(")\n");
591                         break;
592
593                 case V4L2_FRMSIZE_TYPE_CONTINUOUS:
594                         printf("\tFrame size: %ux%u - %ux%u (",
595                                 frame.stepwise.min_width,
596                                 frame.stepwise.min_height,
597                                 frame.stepwise.max_width,
598                                 frame.stepwise.max_height);
599                         video_enum_frame_intervals(dev, frame.pixel_format,
600                                 frame.stepwise.max_width,
601                                 frame.stepwise.max_height);
602                         printf(")\n");
603                         break;
604
605                 case V4L2_FRMSIZE_TYPE_STEPWISE:
606                         printf("\tFrame size: %ux%u - %ux%u (by %ux%u) (\n",
607                                 frame.stepwise.min_width,
608                                 frame.stepwise.min_height,
609                                 frame.stepwise.max_width,
610                                 frame.stepwise.max_height,
611                                 frame.stepwise.step_width,
612                                 frame.stepwise.step_height);
613                         video_enum_frame_intervals(dev, frame.pixel_format,
614                                 frame.stepwise.max_width,
615                                 frame.stepwise.max_height);
616                         printf(")\n");
617                         break;
618
619                 default:
620                         break;
621                 }
622         }
623 }
624 static void video_enum_formats(struct device *dev, enum v4l2_buf_type type)
625 {
626         struct v4l2_fmtdesc fmt;
627         unsigned int i;
628         int ret;
629
630         for (i = 0; ; ++i) {
631                 memset(&fmt, 0, sizeof fmt);
632                 fmt.index = i;
633                 fmt.type = type;
634                 ret = ioctl(dev->fd, VIDIOC_ENUM_FMT, &fmt);
635                 if (ret < 0)
636                         break;
637
638                 if (i != fmt.index)
639                         printf("Warning: driver returned wrong format index "
640                                 "%u.\n", fmt.index);
641                 if (type != fmt.type)
642                         printf("Warning: driver returned wrong format type "
643                                 "%u.\n", fmt.type);
644
645                 printf("\tFormat %u: %s (%08x)\n", i,
646                         v4l2_fourcc_name(fmt.pixelformat), fmt.pixelformat);
647                 printf("\tType: %s (%u)\n", v4l2_buf_type_name(fmt.type),
648                         fmt.type);
649                 printf("\tName: %.32s\n", fmt.description);
650                 video_enum_frame_sizes(dev, fmt.pixelformat);
651                 printf("\n");
652         }
653 }
654
655 static void video_enum_inputs(struct device *dev)
656 {
657         struct v4l2_input input;
658         unsigned int i;
659         int ret;
660
661         for (i = 0; ; ++i) {
662                 memset(&input, 0, sizeof input);
663                 input.index = i;
664                 ret = ioctl(dev->fd, VIDIOC_ENUMINPUT, &input);
665                 if (ret < 0)
666                         break;
667
668                 if (i != input.index)
669                         printf("Warning: driver returned wrong input index "
670                                 "%u.\n", input.index);
671
672                 printf("\tInput %u: %s.\n", i, input.name);
673         }
674
675         printf("\n");
676 }
677
678 static int video_get_input(struct device *dev)
679 {
680         __u32 input;
681         int ret;
682
683         ret = ioctl(dev->fd, VIDIOC_G_INPUT, &input);
684         if (ret < 0) {
685                 printf("Unable to get current input: %s.\n", strerror(errno));
686                 return ret;
687         }
688
689         return input;
690 }
691
692 static int video_set_input(struct device *dev, unsigned int input)
693 {
694         __u32 _input = input;
695         int ret;
696
697         ret = ioctl(dev->fd, VIDIOC_S_INPUT, &_input);
698         if (ret < 0)
699                 printf("Unable to select input %u: %s.\n", input,
700                         strerror(errno));
701
702         return ret;
703 }
704
705 static int video_set_quality(struct device *dev, unsigned int quality)
706 {
707         struct v4l2_jpegcompression jpeg;
708         int ret;
709
710         if (quality == (unsigned int)-1)
711                 return 0;
712
713         memset(&jpeg, 0, sizeof jpeg);
714         jpeg.quality = quality;
715
716         ret = ioctl(dev->fd, VIDIOC_S_JPEGCOMP, &jpeg);
717         if (ret < 0) {
718                 printf("Unable to set quality to %u: %s.\n", quality,
719                         strerror(errno));
720                 return ret;
721         }
722
723         ret = ioctl(dev->fd, VIDIOC_G_JPEGCOMP, &jpeg);
724         if (ret >= 0)
725                 printf("Quality set to %u\n", jpeg.quality);
726
727         return 0;
728 }
729
730 static int video_load_test_pattern(struct device *dev, const char *filename)
731 {
732         unsigned int x, y;
733         uint8_t *data;
734         int ret;
735         int fd;
736
737         /* Load or generate the test pattern */
738         dev->pattern = malloc(dev->bufsize);
739         if (dev->pattern == NULL)
740                 return -ENOMEM;
741
742         if (filename == NULL) {
743                 if (dev->bytesperline == 0) {
744                         printf("Compressed format detect and no test pattern filename given.\n"
745                                 "The test pattern can't be generated automatically.\n");
746                         return -EINVAL;
747                 }
748
749                 data = dev->pattern;
750
751                 for (y = 0; y < dev->height; ++y) {
752                         for (x = 0; x < dev->bytesperline; ++x)
753                                 *data++ = x + y;
754                 }
755
756                 return 0;
757         }
758
759         fd = open(filename, O_RDONLY);
760         if (fd == -1) {
761                 printf("Unable to open test pattern file '%s': %s.\n", filename,
762                         strerror(errno));
763                 return -errno;
764         }
765
766         ret = read(fd, dev->pattern, dev->bufsize);
767         close(fd);
768
769         if (ret != (int)dev->bufsize) {
770                 printf("Test pattern file size %u doesn't match image size %u\n",
771                         ret, dev->bufsize);
772                 return -EINVAL;
773         }
774
775         return 0;
776 }
777
778 static int video_prepare_capture(struct device *dev, int nbufs, unsigned int offset,
779                                  const char *filename)
780 {
781         unsigned int i;
782         int ret;
783
784         /* Allocate and map buffers. */
785         if ((ret = video_alloc_buffers(dev, nbufs, offset)) < 0)
786                 return ret;
787
788         if (dev->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) {
789                 ret = video_load_test_pattern(dev, filename);
790                 if (ret < 0)
791                         return ret;
792         }
793
794         /* Queue the buffers. */
795         for (i = 0; i < dev->nbufs; ++i) {
796                 ret = video_queue_buffer(dev, i);
797                 if (ret < 0)
798                         return ret;
799         }
800
801         return 0;
802 }
803
804 static int video_do_capture(struct device *dev, unsigned int nframes,
805         unsigned int skip, unsigned int delay, const char *filename_prefix,
806         int do_requeue_last)
807 {
808         char *filename = NULL;
809         struct timeval start, end, ts;
810         struct v4l2_buffer buf;
811         unsigned int size;
812         unsigned int i;
813         FILE *file;
814         double bps;
815         double fps;
816         int ret;
817
818         if (filename_prefix != NULL) {
819                 filename = malloc(strlen(filename_prefix) + 12);
820                 if (filename == NULL)
821                         return -ENOMEM;
822         }
823
824         /* Start streaming. */
825         video_enable(dev, 1);
826
827         size = 0;
828
829         for (i = 0; i < nframes; ++i) {
830                 /* Dequeue a buffer. */
831                 memset(&buf, 0, sizeof buf);
832                 buf.type = dev->type;
833                 buf.memory = dev->memtype;
834                 ret = ioctl(dev->fd, VIDIOC_DQBUF, &buf);
835                 if (ret < 0) {
836                         if (errno != EIO) {
837                                 printf("Unable to dequeue buffer (%d).\n", errno);
838                                 goto done;
839                         }
840                         buf.type = dev->type;
841                         buf.memory = dev->memtype;
842                         if (dev->memtype == V4L2_MEMORY_USERPTR)
843                                 buf.m.userptr = (unsigned long)dev->mem[i];
844                 }
845
846                 if (dev->type == V4L2_BUF_TYPE_VIDEO_CAPTURE &&
847                     dev->imagesize != 0 && buf.bytesused != dev->imagesize)
848                         printf("Warning: bytes used %u != image size %u\n",
849                                buf.bytesused, dev->imagesize);
850
851                 size += buf.bytesused;
852
853                 gettimeofday(&ts, NULL);
854                 printf("%u (%u) [%c] %u %u bytes %ld.%06ld %ld.%06ld\n", i, buf.index,
855                         (buf.flags & V4L2_BUF_FLAG_ERROR) ? 'E' : '-',
856                         buf.sequence, buf.bytesused, buf.timestamp.tv_sec,
857                         buf.timestamp.tv_usec, ts.tv_sec, ts.tv_usec);
858
859                 if (i == 0)
860                         start = ts;
861
862                 /* Save the image. */
863                 if (dev->type == V4L2_BUF_TYPE_VIDEO_CAPTURE && filename_prefix && !skip) {
864                         sprintf(filename, "%s-%06u.bin", filename_prefix, i);
865                         file = fopen(filename, "wb");
866                         if (file != NULL) {
867                                 ret = fwrite(dev->mem[buf.index], buf.bytesused, 1, file);
868                                 fclose(file);
869                         }
870                 }
871                 if (skip)
872                         --skip;
873
874                 /* Requeue the buffer. */
875                 if (delay > 0)
876                         usleep(delay * 1000);
877
878                 fflush(stdout);
879
880                 if (i == nframes - dev->nbufs && !do_requeue_last)
881                         continue;
882
883                 ret = video_queue_buffer(dev, buf.index);
884                 if (ret < 0) {
885                         printf("Unable to requeue buffer (%d).\n", errno);
886                         goto done;
887                 }
888         }
889         gettimeofday(&end, NULL);
890
891         /* Stop streaming. */
892         video_enable(dev, 0);
893
894         if (end.tv_sec == start.tv_sec && end.tv_usec == start.tv_usec)
895                 goto done;
896
897         end.tv_sec -= start.tv_sec;
898         end.tv_usec -= start.tv_usec;
899         if (end.tv_usec < 0) {
900                 end.tv_sec--;
901                 end.tv_usec += 1000000;
902         }
903
904         bps = size/(end.tv_usec+1000000.0*end.tv_sec)*1000000.0;
905         fps = (i-1)/(end.tv_usec+1000000.0*end.tv_sec)*1000000.0;
906
907         printf("Captured %u frames in %lu.%06lu seconds (%f fps, %f B/s).\n",
908                 i-1, end.tv_sec, end.tv_usec, fps, bps);
909
910 done:
911         free(filename);
912         return video_free_buffers(dev);
913 }
914
915 #define V4L_BUFFERS_DEFAULT     8
916 #define V4L_BUFFERS_MAX         32
917
918 static void usage(const char *argv0)
919 {
920         printf("Usage: %s [options] device\n", argv0);
921         printf("Supported options:\n");
922         printf("-c, --capture[=nframes]         Capture frames\n");
923         printf("-d, --delay                     Delay (in ms) before requeuing buffers\n");
924         printf("-f, --format format             Set the video format\n");
925         printf("-F, --file[=prefix]             Read/write frames from/to disk\n");
926         printf("-h, --help                      Show this help screen\n");
927         printf("-i, --input input               Select the video input\n");
928         printf("-l, --list-controls             List available controls\n");
929         printf("-n, --nbufs n                   Set the number of video buffers\n");
930         printf("-p, --pause                     Pause before starting the video stream\n");
931         printf("-q, --quality n                 MJPEG quality (0-100)\n");
932         printf("-r, --get-control ctrl          Get control 'ctrl'\n");
933         printf("-s, --size WxH                  Set the frame size\n");
934         printf("-t, --time-per-frame num/denom  Set the time per frame (eg. 1/25 = 25 fps)\n");
935         printf("-u, --userptr                   Use the user pointers streaming method\n");
936         printf("-w, --set-control 'ctrl value'  Set control 'ctrl' to 'value'\n");
937         printf("    --enum-formats              Enumerate formats\n");
938         printf("    --enum-inputs               Enumerate inputs\n");
939         printf("    --no-query                  Don't query capabilities on open\n");
940         printf("    --offset                    User pointer buffer offset from page start\n");
941         printf("    --requeue-last              Requeue the last buffers before streamoff\n");
942         printf("    --skip n                    Skip the first n frames\n");
943         printf("    --sleep-forever             Sleep forever after configuring the device\n");
944 }
945
946 #define OPT_ENUM_FORMATS        256
947 #define OPT_ENUM_INPUTS         257
948 #define OPT_SKIP_FRAMES         258
949 #define OPT_NO_QUERY            259
950 #define OPT_SLEEP_FOREVER       260
951 #define OPT_USERPTR_OFFSET      261
952 #define OPT_REQUEUE_LAST        262
953
954 static struct option opts[] = {
955         {"capture", 2, 0, 'c'},
956         {"delay", 1, 0, 'd'},
957         {"enum-formats", 0, 0, OPT_ENUM_FORMATS},
958         {"enum-inputs", 0, 0, OPT_ENUM_INPUTS},
959         {"file", 2, 0, 'F'},
960         {"format", 1, 0, 'f'},
961         {"help", 0, 0, 'h'},
962         {"input", 1, 0, 'i'},
963         {"list-controls", 0, 0, 'l'},
964         {"nbufs", 1, 0, 'n'},
965         {"no-query", 0, 0, OPT_NO_QUERY},
966         {"offset", 1, 0, OPT_USERPTR_OFFSET},
967         {"pause", 0, 0, 'p'},
968         {"quality", 1, 0, 'q'},
969         {"get-control", 1, 0, 'r'},
970         {"requeue-last", 0, 0, OPT_REQUEUE_LAST},
971         {"size", 1, 0, 's'},
972         {"set-control", 1, 0, 'w'},
973         {"skip", 1, 0, OPT_SKIP_FRAMES},
974         {"sleep-forever", 0, 0, OPT_SLEEP_FOREVER},
975         {"time-per-frame", 1, 0, 't'},
976         {"userptr", 0, 0, 'u'},
977         {0, 0, 0, 0}
978 };
979
980 int main(int argc, char *argv[])
981 {
982         struct device dev;
983         int ret;
984
985         /* Options parsings */
986         int do_file = 0, do_capture = 0, do_pause = 0;
987         int do_set_time_per_frame = 0;
988         int do_enum_formats = 0, do_set_format = 0;
989         int do_enum_inputs = 0, do_set_input = 0;
990         int do_list_controls = 0, do_get_control = 0, do_set_control = 0;
991         int do_sleep_forever = 0, do_requeue_last = 0;
992         int no_query = 0;
993         char *endptr;
994         int c;
995
996         /* Controls */
997         int ctrl_name = 0;
998         int ctrl_value = 0;
999
1000         /* Video buffers */
1001         enum v4l2_memory memtype = V4L2_MEMORY_MMAP;
1002         unsigned int pixelformat = V4L2_PIX_FMT_YUYV;
1003         unsigned int width = 640;
1004         unsigned int height = 480;
1005         unsigned int nbufs = V4L_BUFFERS_DEFAULT;
1006         unsigned int input = 0;
1007         unsigned int skip = 0;
1008         unsigned int quality = (unsigned int)-1;
1009         unsigned int userptr_offset = 0;
1010         struct v4l2_fract time_per_frame = {1, 25};
1011
1012         /* Capture loop */
1013         unsigned int delay = 0, nframes = (unsigned int)-1;
1014         const char *filename = "frame";
1015
1016         opterr = 0;
1017         while ((c = getopt_long(argc, argv, "c::d:f:F::hi:ln:pq:r:s:t:uw:", opts, NULL)) != -1) {
1018
1019                 switch (c) {
1020                 case 'c':
1021                         do_capture = 1;
1022                         if (optarg)
1023                                 nframes = atoi(optarg);
1024                         break;
1025                 case 'd':
1026                         delay = atoi(optarg);
1027                         break;
1028                 case 'f':
1029                         do_set_format = 1;
1030                         if (strcasecmp(optarg, "MJPEG") == 0)
1031                                 pixelformat = V4L2_PIX_FMT_MJPEG;
1032                         else if (strcasecmp(optarg, "YUYV") == 0)
1033                                 pixelformat = V4L2_PIX_FMT_YUYV;
1034                         else if (strcasecmp(optarg, "UYVY") == 0)
1035                                 pixelformat = V4L2_PIX_FMT_UYVY;
1036                         else if (strcasecmp(optarg, "Y16") == 0)
1037                                 pixelformat = V4L2_PIX_FMT_Y16;
1038                         else if (strcasecmp(optarg, "SGRBG10") == 0)
1039                                 pixelformat = V4L2_PIX_FMT_SGRBG10;
1040                         else if (strcasecmp(optarg, "DV") == 0)
1041                                 pixelformat = V4L2_PIX_FMT_DV;
1042                         else {
1043                                 printf("Unsupported video format '%s'\n", optarg);
1044                                 return 1;
1045                         }
1046                         break;
1047                 case 'F':
1048                         do_file = 1;
1049                         if (optarg)
1050                                 filename = optarg;
1051                         break;
1052                 case 'h':
1053                         usage(argv[0]);
1054                         return 0;
1055                 case 'i':
1056                         do_set_input = 1;
1057                         input = atoi(optarg);
1058                         break;
1059                 case 'l':
1060                         do_list_controls = 1;
1061                         break;
1062                 case 'n':
1063                         nbufs = atoi(optarg);
1064                         if (nbufs > V4L_BUFFERS_MAX)
1065                                 nbufs = V4L_BUFFERS_MAX;
1066                         break;
1067                 case 'p':
1068                         do_pause = 1;
1069                         break;
1070                 case 'q':
1071                         quality = atoi(optarg);
1072                         break;
1073                 case 'r':
1074                         ctrl_name = strtol(optarg, &endptr, 0);
1075                         if (*endptr != 0) {
1076                                 printf("Invalid control name '%s'\n", optarg);
1077                                 return 1;
1078                         }
1079                         do_get_control = 1;
1080                         break;
1081                 case 's':
1082                         do_set_format = 1;
1083                         width = strtol(optarg, &endptr, 10);
1084                         if (*endptr != 'x' || endptr == optarg) {
1085                                 printf("Invalid size '%s'\n", optarg);
1086                                 return 1;
1087                         }
1088                         height = strtol(endptr + 1, &endptr, 10);
1089                         if (*endptr != 0) {
1090                                 printf("Invalid size '%s'\n", optarg);
1091                                 return 1;
1092                         }
1093                         break;
1094                 case 't':
1095                         do_set_time_per_frame = 1;
1096                         time_per_frame.numerator = strtol(optarg, &endptr, 10);
1097                         if (*endptr != '/' || endptr == optarg) {
1098                                 printf("Invalid time per frame '%s'\n", optarg);
1099                                 return 1;
1100                         }
1101                         time_per_frame.denominator = strtol(endptr + 1, &endptr, 10);
1102                         if (*endptr != 0) {
1103                                 printf("Invalid time per frame '%s'\n", optarg);
1104                                 return 1;
1105                         }
1106                         break;
1107                 case 'u':
1108                         memtype = V4L2_MEMORY_USERPTR;
1109                         break;
1110                 case 'w':
1111                         ctrl_name = strtol(optarg, &endptr, 0);
1112                         if (*endptr != ' ' || endptr == optarg) {
1113                                 printf("Invalid control name '%s'\n", optarg);
1114                                 return 1;
1115                         }
1116                         ctrl_value = strtol(endptr + 1, &endptr, 0);
1117                         if (*endptr != 0) {
1118                                 printf("Invalid control value '%s'\n", optarg);
1119                                 return 1;
1120                         }
1121                         do_set_control = 1;
1122                         break;
1123                 case OPT_ENUM_FORMATS:
1124                         do_enum_formats = 1;
1125                         break;
1126                 case OPT_ENUM_INPUTS:
1127                         do_enum_inputs = 1;
1128                         break;
1129                 case OPT_NO_QUERY:
1130                         no_query = 1;
1131                         break;
1132                 case OPT_REQUEUE_LAST:
1133                         do_requeue_last = 1;
1134                         break;
1135                 case OPT_SKIP_FRAMES:
1136                         skip = atoi(optarg);
1137                         break;
1138                 case OPT_SLEEP_FOREVER:
1139                         do_sleep_forever = 1;
1140                         break;
1141                 case OPT_USERPTR_OFFSET:
1142                         userptr_offset = atoi(optarg);
1143                         break;
1144                 default:
1145                         printf("Invalid option -%c\n", c);
1146                         printf("Run %s -h for help.\n", argv[0]);
1147                         return 1;
1148                 }
1149         }
1150
1151         if (optind >= argc) {
1152                 usage(argv[0]);
1153                 return 1;
1154         }
1155
1156         if (!do_file)
1157                 filename = NULL;
1158
1159         /* Open the video device. */
1160         ret = video_open(&dev, argv[optind], no_query);
1161         if (ret < 0)
1162                 return 1;
1163
1164         dev.memtype = memtype;
1165
1166         if (do_get_control)
1167                 uvc_get_control(&dev, ctrl_name);
1168         if (do_set_control)
1169                 uvc_set_control(&dev, ctrl_name, ctrl_value);
1170
1171         if (do_list_controls)
1172                 video_list_controls(&dev);
1173
1174         if (do_enum_formats) {
1175                 printf("- Available formats:\n");
1176                 video_enum_formats(&dev, V4L2_BUF_TYPE_VIDEO_CAPTURE);
1177                 video_enum_formats(&dev, V4L2_BUF_TYPE_VIDEO_OUTPUT);
1178                 video_enum_formats(&dev, V4L2_BUF_TYPE_VIDEO_OVERLAY);
1179         }
1180
1181         if (do_enum_inputs) {
1182                 printf("- Available inputs:\n");
1183                 video_enum_inputs(&dev);
1184         }
1185
1186         if (do_set_input) {
1187                 video_set_input(&dev, input);
1188                 ret = video_get_input(&dev);
1189                 printf("Input %d selected\n", ret);
1190         }
1191
1192         /* Set the video format. */
1193         if (do_set_format) {
1194                 if (video_set_format(&dev, width, height, pixelformat) < 0) {
1195                         video_close(&dev);
1196                         return 1;
1197                 }
1198         }
1199
1200         if (!no_query || do_capture)
1201                 video_get_format(&dev);
1202
1203         /* Set the frame rate. */
1204         if (do_set_time_per_frame) {
1205                 if (video_set_framerate(&dev, &time_per_frame) < 0) {
1206                         video_close(&dev);
1207                         return 1;
1208                 }
1209         }
1210
1211         while (do_sleep_forever)
1212                 sleep(1000);
1213
1214         if (!do_capture) {
1215                 video_close(&dev);
1216                 return 0;
1217         }
1218
1219         /* Set the compression quality. */
1220         if (video_set_quality(&dev, quality) < 0) {
1221                 video_close(&dev);
1222                 return 1;
1223         }
1224
1225         if (video_prepare_capture(&dev, nbufs, userptr_offset, filename)) {
1226                 video_close(&dev);
1227                 return 1;
1228         }
1229
1230         if (do_pause) {
1231                 printf("Press enter to start capture\n");
1232                 getchar();
1233         }
1234
1235         if (video_do_capture(&dev, nframes, skip, delay, filename, do_requeue_last) < 0) {
1236                 video_close(&dev);
1237                 return 1;
1238         }
1239
1240         video_close(&dev);
1241         return 0;
1242 }
1243