1 /*
2 * Copyright (c) 2000,2001 Fabrice Bellard
3 * Copyright (c) 2006 Luca Abeni
4 *
5 * This file is part of FFmpeg.
6 *
7 * FFmpeg is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * FFmpeg is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with FFmpeg; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 */
21
22 /**
23 * @file
24 * Video4Linux2 grab interface
25 *
26 * Part of this file is based on the V4L2 video capture example
27 * (http://linuxtv.org/downloads/v4l-dvb-apis/capture-example.html)
28 *
29 * Thanks to Michael Niedermayer for providing the mapping between
30 * V4L2_PIX_FMT_* and AV_PIX_FMT_*
31 */
32
33 #include <stdatomic.h>
34
48 #include <dirent.h>
49
50 #if CONFIG_LIBV4L2
51 #include <libv4l2.h>
52 #endif
53
55
56 #define V4L_ALLFORMATS 3
57 #define V4L_RAWFORMATS 1
58 #define V4L_COMPFORMATS 2
59
60 /**
61 * Return timestamps to the user exactly as returned by the kernel
62 */
63 #define V4L_TS_DEFAULT 0
64 /**
65 * Autodetect the kind of timestamps returned by the kernel and convert to
66 * absolute (wall clock) timestamps.
67 */
69 /**
70 * Assume kernel timestamps are from the monotonic clock and convert to
71 * absolute timestamps.
72 */
73 #define V4L_TS_MONO2ABS 2
74
75 /**
76 * Once the kind of timestamps returned by the kernel have been detected,
77 * the value of the timefilter (NULL or not) determines whether a conversion
78 * takes place.
79 */
80 #define V4L_TS_CONVERT_READY V4L_TS_DEFAULT
81
93
105
110 #if HAVE_POSIX_IOCTL
112 #else
114 #endif
118 };
119
123 };
124
126 {
128 struct v4l2_capability cap;
129 int fd;
130 int err;
132
133 #define SET_WRAPPERS(prefix) do { \
134 s->open_f = prefix ## open; \
135 s->close_f = prefix ## close; \
136 s->dup_f = prefix ## dup; \
137 s->ioctl_f = prefix ## ioctl; \
138 s->read_f = prefix ## read; \
139 s->mmap_f = prefix ## mmap; \
140 s->munmap_f = prefix ## munmap; \
141 } while (0)
142
143 if (
s->use_libv4l2) {
144 #if CONFIG_LIBV4L2
146 #else
149 #endif
150 } else {
152 }
153
154 #define v4l2_open s->open_f
155 #define v4l2_close s->close_f
156 #define v4l2_dup s->dup_f
157 #define v4l2_ioctl s->ioctl_f
158 #define v4l2_read s->read_f
159 #define v4l2_mmap s->mmap_f
160 #define v4l2_munmap s->munmap_f
161
164 }
165
167 if (fd < 0) {
171 return err;
172 }
173
174 if (
v4l2_ioctl(fd, VIDIOC_QUERYCAP, &cap) < 0) {
179 }
180
182 fd, cap.capabilities);
183
184 if (!(cap.capabilities & V4L2_CAP_VIDEO_CAPTURE)) {
188 }
189
190 if (!(cap.capabilities & V4L2_CAP_STREAMING)) {
192 "The device does not support the streaming I/O method.\n");
195 }
196
197 return fd;
198
201 return err;
202 }
203
205 uint32_t pixelformat)
206 {
208 struct v4l2_format fmt = { .type = V4L2_BUF_TYPE_VIDEO_CAPTURE };
209 int res = 0;
210
211 fmt.fmt.pix.width = *
width;
212 fmt.fmt.pix.height = *
height;
213 fmt.fmt.pix.pixelformat = pixelformat;
214 fmt.fmt.pix.field = V4L2_FIELD_ANY;
215
216 /* Some drivers will fail and return EINVAL when the pixelformat
217 is not supported (even if type field is valid and supported) */
220
221 if ((*
width != fmt.fmt.pix.width) || (*
height != fmt.fmt.pix.height)) {
223 "The V4L2 driver changed the video from %dx%d to %dx%d\n",
224 *
width, *
height, fmt.fmt.pix.width, fmt.fmt.pix.height);
225 *
width = fmt.fmt.pix.width;
226 *
height = fmt.fmt.pix.height;
227 }
228
229 if (pixelformat != fmt.fmt.pix.pixelformat) {
231 "The V4L2 driver changed the pixel format "
232 "from 0x%08X to 0x%08X\n",
233 pixelformat, fmt.fmt.pix.pixelformat);
235 }
236
237 if (fmt.fmt.pix.field == V4L2_FIELD_INTERLACED) {
239 "The V4L2 driver is using the interlaced mode\n");
241 }
242
243 return res;
244 }
245
247 {
248 int res;
249 v4l2_std_id std;
250
252 if (res < 0)
253 return 0;
254 if (std & V4L2_STD_NTSC)
255 return 0;
256
257 return 1;
258 }
259
260 #if HAVE_STRUCT_V4L2_FRMIVALENUM_DISCRETE
262 {
264 struct v4l2_frmsizeenum vfse = { .pixel_format = pixelformat };
265
266 while(!
v4l2_ioctl(
s->fd, VIDIOC_ENUM_FRAMESIZES, &vfse)) {
267 switch (vfse.type) {
268 case V4L2_FRMSIZE_TYPE_DISCRETE:
270 vfse.discrete.width, vfse.discrete.height);
271 break;
272 case V4L2_FRMSIZE_TYPE_CONTINUOUS:
273 case V4L2_FRMSIZE_TYPE_STEPWISE:
275 vfse.stepwise.min_width,
276 vfse.stepwise.max_width,
277 vfse.stepwise.step_width,
278 vfse.stepwise.min_height,
279 vfse.stepwise.max_height,
280 vfse.stepwise.step_height);
281 }
282 vfse.index++;
283 }
284 }
285 #endif
286
288 {
290 struct v4l2_fmtdesc vfd = { .type = V4L2_BUF_TYPE_VIDEO_CAPTURE };
291
295
296 vfd.index++;
297
298 if (!(vfd.flags & V4L2_FMT_FLAG_COMPRESSED) &&
302 fmt_name ? fmt_name : "Unsupported",
303 vfd.description);
304 } else if (vfd.flags & V4L2_FMT_FLAG_COMPRESSED &&
309 vfd.description);
310 } else {
311 continue;
312 }
313
314 #ifdef V4L2_FMT_FLAG_EMULATED
315 if (vfd.flags & V4L2_FMT_FLAG_EMULATED)
317 #endif
318 #if HAVE_STRUCT_V4L2_FRMIVALENUM_DISCRETE
319 list_framesizes(
ctx, vfd.pixelformat);
320 #endif
322 }
323 }
324
326 {
329 struct v4l2_standard standard;
330
332 return;
333
334 for (standard.index = 0; ; standard.index++) {
335 if (
v4l2_ioctl(
s->fd, VIDIOC_ENUMSTD, &standard) < 0) {
338 break;
339 } else {
341 return;
342 }
343 }
345 standard.index, (uint64_t)standard.id, standard.name);
346 }
347 }
348
350 {
353 struct v4l2_requestbuffers req = {
354 .type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
356 .memory = V4L2_MEMORY_MMAP
357 };
358
362 return res;
363 }
364
365 if (req.count < 2) {
368 }
369 s->buffers = req.count;
374 }
380 }
381
382 for (
i = 0;
i < req.count;
i++) {
383 struct v4l2_buffer buf = {
384 .type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
386 .memory = V4L2_MEMORY_MMAP
387 };
388 if (
v4l2_ioctl(
s->fd, VIDIOC_QUERYBUF, &buf) < 0) {
391 return res;
392 }
393
394 s->buf_len[
i] = buf.length;
395 if (
s->frame_size > 0 &&
s->buf_len[
i] <
s->frame_size) {
397 "buf_len[%d] = %d < expected frame size %d\n",
398 i,
s->buf_len[
i],
s->frame_size);
400 }
402 PROT_READ | PROT_WRITE, MAP_SHARED,
403 s->fd, buf.m.offset);
404
405 if (
s->buf_start[
i] == MAP_FAILED) {
408 return res;
409 }
410 }
411
412 return 0;
413 }
414
416 {
417 int res = 0;
418
422 } else {
424 }
425
426 return res;
427 }
428
430 {
431 struct v4l2_buffer buf = { 0 };
432 struct buff_data *buf_descriptor = opaque;
434
435 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
436 buf.memory = V4L2_MEMORY_MMAP;
437 buf.index = buf_descriptor->
index;
439
441 }
442
443 #if HAVE_CLOCK_GETTIME && defined(CLOCK_MONOTONIC)
444 static int64_t av_gettime_monotonic(
void)
445 {
447 }
448 #endif
449
451 {
454
457 ts <= now + 1 * AV_TIME_BASE && ts >= now - 10 *
AV_TIME_BASE) {
460 return 0;
461 }
462 #if HAVE_CLOCK_GETTIME && defined(CLOCK_MONOTONIC)
464 now = av_gettime_monotonic();
466 (ts <= now + 1 * AV_TIME_BASE && ts >= now - 10 *
AV_TIME_BASE)) {
470 /* microseconds instead of seconds, MHz instead of Hz */
475 return 0;
476 }
477 }
478 #endif
481 }
482
484 {
486
491 }
492 #if HAVE_CLOCK_GETTIME && defined(CLOCK_MONOTONIC)
495 int64_t nowm = av_gettime_monotonic();
497 s->last_time_m = nowm;
499 }
500 #endif
501 return 0;
502 }
503
505 {
507 struct v4l2_buffer buf = {
508 .type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
509 .memory = V4L2_MEMORY_MMAP
510 };
511 struct timeval buf_ts;
512 int res;
513
515
516 /* FIXME: Some special treatment might be needed in case of loss of signal... */
517 while ((res =
v4l2_ioctl(
s->fd, VIDIOC_DQBUF, &buf)) < 0 && (errno == EINTR));
518 if (res < 0) {
519 if (errno == EAGAIN)
521
525 return res;
526 }
527
528 buf_ts = buf.timestamp;
529
530 if (buf.index >=
s->buffers) {
533 }
535 // always keep at least one buffer queued
537
538 #ifdef V4L2_BUF_FLAG_ERROR
539 if (buf.flags & V4L2_BUF_FLAG_ERROR) {
541 "Dequeued v4l2 buffer contains corrupted data (%d bytes).\n",
542 buf.bytesused);
543 buf.bytesused = 0;
544 } else
545 #endif
546 {
547 /* CPIA is a compressed format and we don't know the exact number of bytes
548 * used by a frame, so set it here as the driver announces it. */
550 s->frame_size = buf.bytesused;
551
552 if (
s->frame_size > 0 && buf.bytesused !=
s->frame_size) {
554 "Dequeued v4l2 buffer contains %d bytes, but %d were expected. Flags: 0x%08X.\n",
555 buf.bytesused,
s->frame_size, buf.flags);
556 buf.bytesused = 0;
557 }
558 }
559
560 /* Image is at s->buff_start[buf.index] */
562 /* when we start getting low on queued buffers, fall back on copying data */
564 if (res < 0) {
567 return res;
568 }
569 memcpy(
pkt->
data,
s->buf_start[buf.index], buf.bytesused);
570
572 if (res) {
574 return res;
575 }
576 } else {
578
579 pkt->
data =
s->buf_start[buf.index];
581
583 if (!buf_descriptor) {
584 /* Something went wrong... Since av_malloc() failed, we cannot even
585 * allocate a buffer for memcpying into it
586 */
589
591 }
592 buf_descriptor->
index = buf.index;
593 buf_descriptor->
s =
s;
594
596 buf_descriptor, 0);
602 }
603 }
604 pkt->
pts = buf_ts.tv_sec * INT64_C(1000000) + buf_ts.tv_usec;
606
608 }
609
611 {
613 enum v4l2_buf_type
type;
615
616 for (
i = 0;
i <
s->buffers;
i++) {
617 struct v4l2_buffer buf = {
618 .type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
620 .memory = V4L2_MEMORY_MMAP
621 };
622
627 return res;
628 }
629 }
631
632 type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
637 return res;
638 }
639
640 return 0;
641 }
642
644 {
645 enum v4l2_buf_type
type;
647
648 type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
649 /* We do not check for the result, because we could
650 * not do anything about it anyway...
651 */
653 for (
i = 0;
i <
s->buffers;
i++) {
655 }
658 }
659
661 {
663 struct v4l2_standard standard = { 0 };
664 struct v4l2_streamparm streamparm = { 0 };
665 struct v4l2_fract *tpf;
668
674 }
675
680 /* set tv standard */
683 if (
v4l2_ioctl(
s->fd, VIDIOC_ENUMSTD, &standard) < 0) {
685 break;
686 }
688 break;
689 }
693 }
694
695 if (
v4l2_ioctl(
s->fd, VIDIOC_S_STD, &standard.id) < 0) {
699 }
700 } else {
702 "This device does not support any standard\n");
703 }
704 }
705
706 /* get standard */
708 tpf = &standard.frameperiod;
711 if (
v4l2_ioctl(
s->fd, VIDIOC_ENUMSTD, &standard) < 0) {
714 #ifdef ENODATA
716 #endif
717 ) {
718 tpf = &streamparm.parm.capture.timeperframe;
719 break;
720 }
723 }
724 if (standard.id ==
s->std_id) {
726 "Current standard: %s, id: %"PRIx64", frameperiod: %d/%d\n",
727 standard.name, (uint64_t)standard.id, tpf->numerator, tpf->denominator);
728 break;
729 }
730 }
731 } else {
732 tpf = &streamparm.parm.capture.timeperframe;
733 }
734
735 streamparm.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
736 if (
v4l2_ioctl(
s->fd, VIDIOC_G_PARM, &streamparm) < 0) {
739 }
else if (framerate_q.
num && framerate_q.
den) {
740 if (streamparm.parm.capture.capability & V4L2_CAP_TIMEPERFRAME) {
741 tpf = &streamparm.parm.capture.timeperframe;
742
744 framerate_q.
den, framerate_q.
num);
745 tpf->numerator = framerate_q.
den;
746 tpf->denominator = framerate_q.
num;
747
748 if (
v4l2_ioctl(
s->fd, VIDIOC_S_PARM, &streamparm) < 0) {
753 }
754
755 if (framerate_q.
num != tpf->denominator ||
756 framerate_q.
den != tpf->numerator) {
758 "The driver changed the time per frame from "
759 "%d/%d to %d/%d\n",
760 framerate_q.
den, framerate_q.
num,
761 tpf->numerator, tpf->denominator);
762 }
763 } else {
765 "The driver does not permit changing the time per frame\n");
766 }
767 }
768 if (tpf->denominator > 0 && tpf->numerator > 0) {
772 } else
774
775 return 0;
776 }
777
782 uint32_t *desired_format,
784 {
786
788
789 if (*desired_format) {
792 *desired_format = 0;
795 }
796 }
797
798 if (!*desired_format) {
805
809 break;
812 *desired_format = 0;
813 }
814 }
815
816 if (*desired_format == 0) {
818 "codec '%s' (id %d), pixel format '%s' (id %d)\n",
822 }
823 }
824
829 }
830
832 {
835 return 0;
836 }
837
839 {
842 int res = 0;
843 uint32_t desired_format;
846 struct v4l2_input
input = { 0 };
847
849 if (!st)
851
852 #if CONFIG_LIBV4L2
853 /* silence libv4l2 logging. if fopen() fails v4l2_log_file will be NULL
854 and errors will get sent to stderr */
856 v4l2_log_file = fopen("/dev/null", "w");
857 #endif
858
862
863 if (
s->channel != -1) {
864 /* set video input */
866 if (
v4l2_ioctl(
s->fd, VIDIOC_S_INPUT, &
s->channel) < 0) {
870 }
871 } else {
872 /* get current video input */
873 if (
v4l2_ioctl(
s->fd, VIDIOC_G_INPUT, &
s->channel) < 0) {
877 }
878 }
879
880 /* enum input */
886 }
890
891 if (
s->list_format) {
895 }
896
897 if (
s->list_standard) {
901 }
902
904
905 if (
s->pixel_format) {
907
910
912
916
919 }
920 }
921
922 if (!
s->width && !
s->height) {
923 struct v4l2_format fmt = { .type = V4L2_BUF_TYPE_VIDEO_CAPTURE };
924
926 "Querying the device for the current frame size\n");
932 }
933
934 s->width = fmt.fmt.pix.width;
935 s->height = fmt.fmt.pix.height;
937 "Setting frame size to %dx%d\n",
s->width,
s->height);
938 }
939
941 if (res < 0)
943
944 /* If no pixel_format was specified, the codec_id was not known up
945 * until now. Set video_codec_id in the context, as codec_id will
946 * not be available outside this function
947 */
950
953
954 s->pixelformat = desired_format;
955
958
962 s->width,
s->height, 1);
963
967
969
977 }
978 if (desired_format == V4L2_PIX_FMT_YVU420)
980 else if (desired_format == V4L2_PIX_FMT_YVU410)
986
987 return 0;
988
991 return res;
992 }
993
995 {
996 int res;
997
999 return res;
1000 }
1001
1003 }
1004
1006 {
1008
1011 "close.\n");
1012
1014
1017 return 0;
1018 }
1019
1021 {
1022 return !strncmp(
name,
"video", 5) ||
1023 !strncmp(
name,
"radio", 5) ||
1024 !strncmp(
name,
"vbi", 3) ||
1025 !strncmp(
name,
"v4l-subdev", 10);
1026 }
1027
1029 {
1031 DIR *dir;
1032 struct dirent *
entry;
1034
1035 if (!device_list)
1037
1038 dir = opendir("/dev");
1039 if (!dir) {
1043 }
1044 while ((
entry = readdir(dir))) {
1046 struct v4l2_capability cap;
1048 char device_name[256];
1049
1051 continue;
1052
1054 if (
size >=
sizeof(device_name)) {
1057 break;
1058 }
1059
1061 continue;
1062
1063 if (
v4l2_ioctl(fd, VIDIOC_QUERYCAP, &cap) < 0) {
1067 }
1068
1070 if (!device) {
1073 }
1079 }
1080
1084
1086 continue;
1087
1089 if (device) {
1093 }
1095 break;
1096 }
1097 closedir(dir);
1099 }
1100
1101 #define OFFSET(x) offsetof(struct video_data, x)
1102 #define DEC AV_OPT_FLAG_DECODING_PARAM
1103
1111
1112 {
"list_formats",
"list available formats and exit",
OFFSET(list_format),
AV_OPT_TYPE_INT, {.i64 = 0 }, 0, INT_MAX,
DEC, .unit =
"list_formats" },
1116
1117 {
"list_standards",
"list supported standards and exit",
OFFSET(list_standard),
AV_OPT_TYPE_INT, {.i64 = 0 }, 0, 1,
DEC, .unit =
"list_standards" },
1118 {
"all",
"show all supported standards",
OFFSET(list_standard),
AV_OPT_TYPE_CONST, {.i64 = 1 }, 0, 0,
DEC, .unit =
"list_standards" },
1119
1120 {
"timestamps",
"set type of timestamps for grabbed frames",
OFFSET(ts_mode),
AV_OPT_TYPE_INT, {.i64 = 0 }, 0, 2,
DEC, .unit =
"timestamps" },
1121 {
"ts",
"set type of timestamps for grabbed frames",
OFFSET(ts_mode),
AV_OPT_TYPE_INT, {.i64 = 0 }, 0, 2,
DEC, .unit =
"timestamps" },
1125 {
"use_libv4l2",
"use libv4l2 (v4l-utils) conversion functions",
OFFSET(use_libv4l2),
AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1,
DEC },
1127 };
1128
1135 };
1136
1138 .
p.
name =
"video4linux2,v4l2",
1148 };