Merge tag 'docs-5.0-fixes' of git://git.lwn.net/linux
[sfrench/cifs-2.6.git] / Documentation / media / uapi / v4l / capture.c.rst
1 .. Permission is granted to copy, distribute and/or modify this
2 .. document under the terms of the GNU Free Documentation License,
3 .. Version 1.1 or any later version published by the Free Software
4 .. Foundation, with no Invariant Sections, no Front-Cover Texts
5 .. and no Back-Cover Texts. A copy of the license is included at
6 .. Documentation/media/uapi/fdl-appendix.rst.
7 ..
8 .. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
9
10 file: media/v4l/capture.c
11 =========================
12
13 .. code-block:: c
14
15     /*
16      *  V4L2 video capture example
17      *
18      *  This program can be used and distributed without restrictions.
19      *
20      *      This program is provided with the V4L2 API
21      * see https://linuxtv.org/docs.php for more information
22      */
23
24     #include <stdio.h>
25     #include <stdlib.h>
26     #include <string.h>
27     #include <assert.h>
28
29     #include <getopt.h>             /* getopt_long() */
30
31     #include <fcntl.h>              /* low-level i/o */
32     #include <unistd.h>
33     #include <errno.h>
34     #include <sys/stat.h>
35     #include <sys/types.h>
36     #include <sys/time.h>
37     #include <sys/mman.h>
38     #include <sys/ioctl.h>
39
40     #include <linux/videodev2.h>
41
42     #define CLEAR(x) memset(&(x), 0, sizeof(x))
43
44     enum io_method {
45             IO_METHOD_READ,
46             IO_METHOD_MMAP,
47             IO_METHOD_USERPTR,
48     };
49
50     struct buffer {
51             void   *start;
52             size_t  length;
53     };
54
55     static char            *dev_name;
56     static enum io_method   io = IO_METHOD_MMAP;
57     static int              fd = -1;
58     struct buffer          *buffers;
59     static unsigned int     n_buffers;
60     static int              out_buf;
61     static int              force_format;
62     static int              frame_count = 70;
63
64     static void errno_exit(const char *s)
65     {
66             fprintf(stderr, "%s error %d, %s\\n", s, errno, strerror(errno));
67             exit(EXIT_FAILURE);
68     }
69
70     static int xioctl(int fh, int request, void *arg)
71     {
72             int r;
73
74             do {
75                     r = ioctl(fh, request, arg);
76             } while (-1 == r && EINTR == errno);
77
78             return r;
79     }
80
81     static void process_image(const void *p, int size)
82     {
83             if (out_buf)
84                     fwrite(p, size, 1, stdout);
85
86             fflush(stderr);
87             fprintf(stderr, ".");
88             fflush(stdout);
89     }
90
91     static int read_frame(void)
92     {
93             struct v4l2_buffer buf;
94             unsigned int i;
95
96             switch (io) {
97             case IO_METHOD_READ:
98                     if (-1 == read(fd, buffers[0].start, buffers[0].length)) {
99                             switch (errno) {
100                             case EAGAIN:
101                                     return 0;
102
103                             case EIO:
104                                     /* Could ignore EIO, see spec. */
105
106                                     /* fall through */
107
108                             default:
109                                     errno_exit("read");
110                             }
111                     }
112
113                     process_image(buffers[0].start, buffers[0].length);
114                     break;
115
116             case IO_METHOD_MMAP:
117                     CLEAR(buf);
118
119                     buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
120                     buf.memory = V4L2_MEMORY_MMAP;
121
122                     if (-1 == xioctl(fd, VIDIOC_DQBUF, &buf)) {
123                             switch (errno) {
124                             case EAGAIN:
125                                     return 0;
126
127                             case EIO:
128                                     /* Could ignore EIO, see spec. */
129
130                                     /* fall through */
131
132                             default:
133                                     errno_exit("VIDIOC_DQBUF");
134                             }
135                     }
136
137                     assert(buf.index < n_buffers);
138
139                     process_image(buffers[buf.index].start, buf.bytesused);
140
141                     if (-1 == xioctl(fd, VIDIOC_QBUF, &buf))
142                             errno_exit("VIDIOC_QBUF");
143                     break;
144
145             case IO_METHOD_USERPTR:
146                     CLEAR(buf);
147
148                     buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
149                     buf.memory = V4L2_MEMORY_USERPTR;
150
151                     if (-1 == xioctl(fd, VIDIOC_DQBUF, &buf)) {
152                             switch (errno) {
153                             case EAGAIN:
154                                     return 0;
155
156                             case EIO:
157                                     /* Could ignore EIO, see spec. */
158
159                                     /* fall through */
160
161                             default:
162                                     errno_exit("VIDIOC_DQBUF");
163                             }
164                     }
165
166                     for (i = 0; i < n_buffers; ++i)
167                             if (buf.m.userptr == (unsigned long)buffers[i].start
168                                 && buf.length == buffers[i].length)
169                                     break;
170
171                     assert(i < n_buffers);
172
173                     process_image((void *)buf.m.userptr, buf.bytesused);
174
175                     if (-1 == xioctl(fd, VIDIOC_QBUF, &buf))
176                             errno_exit("VIDIOC_QBUF");
177                     break;
178             }
179
180             return 1;
181     }
182
183     static void mainloop(void)
184     {
185             unsigned int count;
186
187             count = frame_count;
188
189             while (count-- > 0) {
190                     for (;;) {
191                             fd_set fds;
192                             struct timeval tv;
193                             int r;
194
195                             FD_ZERO(&fds);
196                             FD_SET(fd, &fds);
197
198                             /* Timeout. */
199                             tv.tv_sec = 2;
200                             tv.tv_usec = 0;
201
202                             r = select(fd + 1, &fds, NULL, NULL, &tv);
203
204                             if (-1 == r) {
205                                     if (EINTR == errno)
206                                             continue;
207                                     errno_exit("select");
208                             }
209
210                             if (0 == r) {
211                                     fprintf(stderr, "select timeout\\n");
212                                     exit(EXIT_FAILURE);
213                             }
214
215                             if (read_frame())
216                                     break;
217                             /* EAGAIN - continue select loop. */
218                     }
219             }
220     }
221
222     static void stop_capturing(void)
223     {
224             enum v4l2_buf_type type;
225
226             switch (io) {
227             case IO_METHOD_READ:
228                     /* Nothing to do. */
229                     break;
230
231             case IO_METHOD_MMAP:
232             case IO_METHOD_USERPTR:
233                     type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
234                     if (-1 == xioctl(fd, VIDIOC_STREAMOFF, &type))
235                             errno_exit("VIDIOC_STREAMOFF");
236                     break;
237             }
238     }
239
240     static void start_capturing(void)
241     {
242             unsigned int i;
243             enum v4l2_buf_type type;
244
245             switch (io) {
246             case IO_METHOD_READ:
247                     /* Nothing to do. */
248                     break;
249
250             case IO_METHOD_MMAP:
251                     for (i = 0; i < n_buffers; ++i) {
252                             struct v4l2_buffer buf;
253
254                             CLEAR(buf);
255                             buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
256                             buf.memory = V4L2_MEMORY_MMAP;
257                             buf.index = i;
258
259                             if (-1 == xioctl(fd, VIDIOC_QBUF, &buf))
260                                     errno_exit("VIDIOC_QBUF");
261                     }
262                     type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
263                     if (-1 == xioctl(fd, VIDIOC_STREAMON, &type))
264                             errno_exit("VIDIOC_STREAMON");
265                     break;
266
267             case IO_METHOD_USERPTR:
268                     for (i = 0; i < n_buffers; ++i) {
269                             struct v4l2_buffer buf;
270
271                             CLEAR(buf);
272                             buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
273                             buf.memory = V4L2_MEMORY_USERPTR;
274                             buf.index = i;
275                             buf.m.userptr = (unsigned long)buffers[i].start;
276                             buf.length = buffers[i].length;
277
278                             if (-1 == xioctl(fd, VIDIOC_QBUF, &buf))
279                                     errno_exit("VIDIOC_QBUF");
280                     }
281                     type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
282                     if (-1 == xioctl(fd, VIDIOC_STREAMON, &type))
283                             errno_exit("VIDIOC_STREAMON");
284                     break;
285             }
286     }
287
288     static void uninit_device(void)
289     {
290             unsigned int i;
291
292             switch (io) {
293             case IO_METHOD_READ:
294                     free(buffers[0].start);
295                     break;
296
297             case IO_METHOD_MMAP:
298                     for (i = 0; i < n_buffers; ++i)
299                             if (-1 == munmap(buffers[i].start, buffers[i].length))
300                                     errno_exit("munmap");
301                     break;
302
303             case IO_METHOD_USERPTR:
304                     for (i = 0; i < n_buffers; ++i)
305                             free(buffers[i].start);
306                     break;
307             }
308
309             free(buffers);
310     }
311
312     static void init_read(unsigned int buffer_size)
313     {
314             buffers = calloc(1, sizeof(*buffers));
315
316             if (!buffers) {
317                     fprintf(stderr, "Out of memory\\n");
318                     exit(EXIT_FAILURE);
319             }
320
321             buffers[0].length = buffer_size;
322             buffers[0].start = malloc(buffer_size);
323
324             if (!buffers[0].start) {
325                     fprintf(stderr, "Out of memory\\n");
326                     exit(EXIT_FAILURE);
327             }
328     }
329
330     static void init_mmap(void)
331     {
332             struct v4l2_requestbuffers req;
333
334             CLEAR(req);
335
336             req.count = 4;
337             req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
338             req.memory = V4L2_MEMORY_MMAP;
339
340             if (-1 == xioctl(fd, VIDIOC_REQBUFS, &req)) {
341                     if (EINVAL == errno) {
342                             fprintf(stderr, "%s does not support "
343                                      "memory mappingn", dev_name);
344                             exit(EXIT_FAILURE);
345                     } else {
346                             errno_exit("VIDIOC_REQBUFS");
347                     }
348             }
349
350             if (req.count < 2) {
351                     fprintf(stderr, "Insufficient buffer memory on %s\\n",
352                              dev_name);
353                     exit(EXIT_FAILURE);
354             }
355
356             buffers = calloc(req.count, sizeof(*buffers));
357
358             if (!buffers) {
359                     fprintf(stderr, "Out of memory\\n");
360                     exit(EXIT_FAILURE);
361             }
362
363             for (n_buffers = 0; n_buffers < req.count; ++n_buffers) {
364                     struct v4l2_buffer buf;
365
366                     CLEAR(buf);
367
368                     buf.type        = V4L2_BUF_TYPE_VIDEO_CAPTURE;
369                     buf.memory      = V4L2_MEMORY_MMAP;
370                     buf.index       = n_buffers;
371
372                     if (-1 == xioctl(fd, VIDIOC_QUERYBUF, &buf))
373                             errno_exit("VIDIOC_QUERYBUF");
374
375                     buffers[n_buffers].length = buf.length;
376                     buffers[n_buffers].start =
377                             mmap(NULL /* start anywhere */,
378                                   buf.length,
379                                   PROT_READ | PROT_WRITE /* required */,
380                                   MAP_SHARED /* recommended */,
381                                   fd, buf.m.offset);
382
383                     if (MAP_FAILED == buffers[n_buffers].start)
384                             errno_exit("mmap");
385             }
386     }
387
388     static void init_userp(unsigned int buffer_size)
389     {
390             struct v4l2_requestbuffers req;
391
392             CLEAR(req);
393
394             req.count  = 4;
395             req.type   = V4L2_BUF_TYPE_VIDEO_CAPTURE;
396             req.memory = V4L2_MEMORY_USERPTR;
397
398             if (-1 == xioctl(fd, VIDIOC_REQBUFS, &req)) {
399                     if (EINVAL == errno) {
400                             fprintf(stderr, "%s does not support "
401                                      "user pointer i/on", dev_name);
402                             exit(EXIT_FAILURE);
403                     } else {
404                             errno_exit("VIDIOC_REQBUFS");
405                     }
406             }
407
408             buffers = calloc(4, sizeof(*buffers));
409
410             if (!buffers) {
411                     fprintf(stderr, "Out of memory\\n");
412                     exit(EXIT_FAILURE);
413             }
414
415             for (n_buffers = 0; n_buffers < 4; ++n_buffers) {
416                     buffers[n_buffers].length = buffer_size;
417                     buffers[n_buffers].start = malloc(buffer_size);
418
419                     if (!buffers[n_buffers].start) {
420                             fprintf(stderr, "Out of memory\\n");
421                             exit(EXIT_FAILURE);
422                     }
423             }
424     }
425
426     static void init_device(void)
427     {
428             struct v4l2_capability cap;
429             struct v4l2_cropcap cropcap;
430             struct v4l2_crop crop;
431             struct v4l2_format fmt;
432             unsigned int min;
433
434             if (-1 == xioctl(fd, VIDIOC_QUERYCAP, &cap)) {
435                     if (EINVAL == errno) {
436                             fprintf(stderr, "%s is no V4L2 device\\n",
437                                      dev_name);
438                             exit(EXIT_FAILURE);
439                     } else {
440                             errno_exit("VIDIOC_QUERYCAP");
441                     }
442             }
443
444             if (!(cap.capabilities & V4L2_CAP_VIDEO_CAPTURE)) {
445                     fprintf(stderr, "%s is no video capture device\\n",
446                              dev_name);
447                     exit(EXIT_FAILURE);
448             }
449
450             switch (io) {
451             case IO_METHOD_READ:
452                     if (!(cap.capabilities & V4L2_CAP_READWRITE)) {
453                             fprintf(stderr, "%s does not support read i/o\\n",
454                                      dev_name);
455                             exit(EXIT_FAILURE);
456                     }
457                     break;
458
459             case IO_METHOD_MMAP:
460             case IO_METHOD_USERPTR:
461                     if (!(cap.capabilities & V4L2_CAP_STREAMING)) {
462                             fprintf(stderr, "%s does not support streaming i/o\\n",
463                                      dev_name);
464                             exit(EXIT_FAILURE);
465                     }
466                     break;
467             }
468
469
470             /* Select video input, video standard and tune here. */
471
472
473             CLEAR(cropcap);
474
475             cropcap.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
476
477             if (0 == xioctl(fd, VIDIOC_CROPCAP, &cropcap)) {
478                     crop.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
479                     crop.c = cropcap.defrect; /* reset to default */
480
481                     if (-1 == xioctl(fd, VIDIOC_S_CROP, &crop)) {
482                             switch (errno) {
483                             case EINVAL:
484                                     /* Cropping not supported. */
485                                     break;
486                             default:
487                                     /* Errors ignored. */
488                                     break;
489                             }
490                     }
491             } else {
492                     /* Errors ignored. */
493             }
494
495
496             CLEAR(fmt);
497
498             fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
499             if (force_format) {
500                     fmt.fmt.pix.width       = 640;
501                     fmt.fmt.pix.height      = 480;
502                     fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;
503                     fmt.fmt.pix.field       = V4L2_FIELD_INTERLACED;
504
505                     if (-1 == xioctl(fd, VIDIOC_S_FMT, &fmt))
506                             errno_exit("VIDIOC_S_FMT");
507
508                     /* Note VIDIOC_S_FMT may change width and height. */
509             } else {
510                     /* Preserve original settings as set by v4l2-ctl for example */
511                     if (-1 == xioctl(fd, VIDIOC_G_FMT, &fmt))
512                             errno_exit("VIDIOC_G_FMT");
513             }
514
515             /* Buggy driver paranoia. */
516             min = fmt.fmt.pix.width * 2;
517             if (fmt.fmt.pix.bytesperline < min)
518                     fmt.fmt.pix.bytesperline = min;
519             min = fmt.fmt.pix.bytesperline * fmt.fmt.pix.height;
520             if (fmt.fmt.pix.sizeimage < min)
521                     fmt.fmt.pix.sizeimage = min;
522
523             switch (io) {
524             case IO_METHOD_READ:
525                     init_read(fmt.fmt.pix.sizeimage);
526                     break;
527
528             case IO_METHOD_MMAP:
529                     init_mmap();
530                     break;
531
532             case IO_METHOD_USERPTR:
533                     init_userp(fmt.fmt.pix.sizeimage);
534                     break;
535             }
536     }
537
538     static void close_device(void)
539     {
540             if (-1 == close(fd))
541                     errno_exit("close");
542
543             fd = -1;
544     }
545
546     static void open_device(void)
547     {
548             struct stat st;
549
550             if (-1 == stat(dev_name, &st)) {
551                     fprintf(stderr, "Cannot identify '%s': %d, %s\\n",
552                              dev_name, errno, strerror(errno));
553                     exit(EXIT_FAILURE);
554             }
555
556             if (!S_ISCHR(st.st_mode)) {
557                     fprintf(stderr, "%s is no devicen", dev_name);
558                     exit(EXIT_FAILURE);
559             }
560
561             fd = open(dev_name, O_RDWR /* required */ | O_NONBLOCK, 0);
562
563             if (-1 == fd) {
564                     fprintf(stderr, "Cannot open '%s': %d, %s\\n",
565                              dev_name, errno, strerror(errno));
566                     exit(EXIT_FAILURE);
567             }
568     }
569
570     static void usage(FILE *fp, int argc, char **argv)
571     {
572             fprintf(fp,
573                      "Usage: %s [options]\\n\\n"
574                      "Version 1.3\\n"
575                      "Options:\\n"
576                      "-d | --device name   Video device name [%s]n"
577                      "-h | --help          Print this messagen"
578                      "-m | --mmap          Use memory mapped buffers [default]n"
579                      "-r | --read          Use read() callsn"
580                      "-u | --userp         Use application allocated buffersn"
581                      "-o | --output        Outputs stream to stdoutn"
582                      "-f | --format        Force format to 640x480 YUYVn"
583                      "-c | --count         Number of frames to grab [%i]n"
584                      "",
585                      argv[0], dev_name, frame_count);
586     }
587
588     static const char short_options[] = "d:hmruofc:";
589
590     static const struct option
591     long_options[] = {
592             { "device", required_argument, NULL, 'd' },
593             { "help",   no_argument,       NULL, 'h' },
594             { "mmap",   no_argument,       NULL, 'm' },
595             { "read",   no_argument,       NULL, 'r' },
596             { "userp",  no_argument,       NULL, 'u' },
597             { "output", no_argument,       NULL, 'o' },
598             { "format", no_argument,       NULL, 'f' },
599             { "count",  required_argument, NULL, 'c' },
600             { 0, 0, 0, 0 }
601     };
602
603     int main(int argc, char **argv)
604     {
605             dev_name = "/dev/video0";
606
607             for (;;) {
608                     int idx;
609                     int c;
610
611                     c = getopt_long(argc, argv,
612                                     short_options, long_options, &idx);
613
614                     if (-1 == c)
615                             break;
616
617                     switch (c) {
618                     case 0: /* getopt_long() flag */
619                             break;
620
621                     case 'd':
622                             dev_name = optarg;
623                             break;
624
625                     case 'h':
626                             usage(stdout, argc, argv);
627                             exit(EXIT_SUCCESS);
628
629                     case 'm':
630                             io = IO_METHOD_MMAP;
631                             break;
632
633                     case 'r':
634                             io = IO_METHOD_READ;
635                             break;
636
637                     case 'u':
638                             io = IO_METHOD_USERPTR;
639                             break;
640
641                     case 'o':
642                             out_buf++;
643                             break;
644
645                     case 'f':
646                             force_format++;
647                             break;
648
649                     case 'c':
650                             errno = 0;
651                             frame_count = strtol(optarg, NULL, 0);
652                             if (errno)
653                                     errno_exit(optarg);
654                             break;
655
656                     default:
657                             usage(stderr, argc, argv);
658                             exit(EXIT_FAILURE);
659                     }
660             }
661
662             open_device();
663             init_device();
664             start_capturing();
665             mainloop();
666             stop_capturing();
667             uninit_device();
668             close_device();
669             fprintf(stderr, "\\n");
670             return 0;
671     }