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