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
47 #include <dirent.h>
48
49 #if CONFIG_LIBV4L2
50 #include <libv4l2.h>
51 #endif
52
54
55 #define V4L_ALLFORMATS 3
56 #define V4L_RAWFORMATS 1
57 #define V4L_COMPFORMATS 2
58
59 /**
60 * Return timestamps to the user exactly as returned by the kernel
61 */
62 #define V4L_TS_DEFAULT 0
63 /**
64 * Autodetect the kind of timestamps returned by the kernel and convert to
65 * absolute (wall clock) timestamps.
66 */
68 /**
69 * Assume kernel timestamps are from the monotonic clock and convert to
70 * absolute timestamps.
71 */
72 #define V4L_TS_MONO2ABS 2
73
74 /**
75 * Once the kind of timestamps returned by the kernel have been detected,
76 * the value of the timefilter (NULL or not) determines whether a conversion
77 * takes place.
78 */
79 #define V4L_TS_CONVERT_READY V4L_TS_DEFAULT
80
92
104
109 #ifdef __GLIBC__
111 #else
113 #endif
115 void *(*mmap_f)(
void *start,
size_t length,
int prot,
int flags,
int fd, int64_t
offset);
117 };
118
122 };
123
125 {
127 struct v4l2_capability cap;
128 int fd;
129 int err;
131
132 #define SET_WRAPPERS(prefix) do { \
133 s->open_f = prefix ## open; \
134 s->close_f = prefix ## close; \
135 s->dup_f = prefix ## dup; \
136 s->ioctl_f = prefix ## ioctl; \
137 s->read_f = prefix ## read; \
138 s->mmap_f = prefix ## mmap; \
139 s->munmap_f = prefix ## munmap; \
140 } while (0)
141
142 if (
s->use_libv4l2) {
143 #if CONFIG_LIBV4L2
145 #else
148 #endif
149 } else {
151 }
152
153 #define v4l2_open s->open_f
154 #define v4l2_close s->close_f
155 #define v4l2_dup s->dup_f
156 #define v4l2_ioctl s->ioctl_f
157 #define v4l2_read s->read_f
158 #define v4l2_mmap s->mmap_f
159 #define v4l2_munmap s->munmap_f
160
163 }
164
166 if (fd < 0) {
170 return err;
171 }
172
173 if (
v4l2_ioctl(fd, VIDIOC_QUERYCAP, &cap) < 0) {
178 }
179
181 fd, cap.capabilities);
182
183 if (!(cap.capabilities & V4L2_CAP_VIDEO_CAPTURE)) {
187 }
188
189 if (!(cap.capabilities & V4L2_CAP_STREAMING)) {
191 "The device does not support the streaming I/O method.\n");
194 }
195
196 return fd;
197
200 return err;
201 }
202
204 uint32_t pixelformat)
205 {
207 struct v4l2_format fmt = { .type = V4L2_BUF_TYPE_VIDEO_CAPTURE };
208 int res = 0;
209
210 fmt.fmt.pix.width = *
width;
211 fmt.fmt.pix.height = *
height;
212 fmt.fmt.pix.pixelformat = pixelformat;
213 fmt.fmt.pix.field = V4L2_FIELD_ANY;
214
215 /* Some drivers will fail and return EINVAL when the pixelformat
216 is not supported (even if type field is valid and supported) */
219
220 if ((*
width != fmt.fmt.pix.width) || (*
height != fmt.fmt.pix.height)) {
222 "The V4L2 driver changed the video from %dx%d to %dx%d\n",
223 *
width, *
height, fmt.fmt.pix.width, fmt.fmt.pix.height);
224 *
width = fmt.fmt.pix.width;
225 *
height = fmt.fmt.pix.height;
226 }
227
228 if (pixelformat != fmt.fmt.pix.pixelformat) {
230 "The V4L2 driver changed the pixel format "
231 "from 0x%08X to 0x%08X\n",
232 pixelformat, fmt.fmt.pix.pixelformat);
234 }
235
236 if (fmt.fmt.pix.field == V4L2_FIELD_INTERLACED) {
238 "The V4L2 driver is using the interlaced mode\n");
240 }
241
242 return res;
243 }
244
246 {
247 int res;
248 v4l2_std_id std;
249
251 if (res < 0)
252 return 0;
253 if (std & V4L2_STD_NTSC)
254 return 0;
255
256 return 1;
257 }
258
259 #if HAVE_STRUCT_V4L2_FRMIVALENUM_DISCRETE
261 {
263 struct v4l2_frmsizeenum vfse = { .pixel_format = pixelformat };
264
265 while(!
v4l2_ioctl(
s->fd, VIDIOC_ENUM_FRAMESIZES, &vfse)) {
266 switch (vfse.type) {
267 case V4L2_FRMSIZE_TYPE_DISCRETE:
269 vfse.discrete.width, vfse.discrete.height);
270 break;
271 case V4L2_FRMSIZE_TYPE_CONTINUOUS:
272 case V4L2_FRMSIZE_TYPE_STEPWISE:
274 vfse.stepwise.min_width,
275 vfse.stepwise.max_width,
276 vfse.stepwise.step_width,
277 vfse.stepwise.min_height,
278 vfse.stepwise.max_height,
279 vfse.stepwise.step_height);
280 }
281 vfse.index++;
282 }
283 }
284 #endif
285
287 {
289 struct v4l2_fmtdesc vfd = { .type = V4L2_BUF_TYPE_VIDEO_CAPTURE };
290
294
295 vfd.index++;
296
297 if (!(vfd.flags & V4L2_FMT_FLAG_COMPRESSED) &&
301 fmt_name ? fmt_name : "Unsupported",
302 vfd.description);
303 } else if (vfd.flags & V4L2_FMT_FLAG_COMPRESSED &&
308 vfd.description);
309 } else {
310 continue;
311 }
312
313 #ifdef V4L2_FMT_FLAG_EMULATED
314 if (vfd.flags & V4L2_FMT_FLAG_EMULATED)
316 #endif
317 #if HAVE_STRUCT_V4L2_FRMIVALENUM_DISCRETE
318 list_framesizes(
ctx, vfd.pixelformat);
319 #endif
321 }
322 }
323
325 {
328 struct v4l2_standard standard;
329
331 return;
332
333 for (standard.index = 0; ; standard.index++) {
334 if (
v4l2_ioctl(
s->fd, VIDIOC_ENUMSTD, &standard) < 0) {
337 break;
338 } else {
340 return;
341 }
342 }
344 standard.index, (uint64_t)standard.id, standard.name);
345 }
346 }
347
349 {
352 struct v4l2_requestbuffers req = {
353 .type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
355 .memory = V4L2_MEMORY_MMAP
356 };
357
361 return res;
362 }
363
364 if (req.count < 2) {
367 }
368 s->buffers = req.count;
373 }
379 }
380
381 for (
i = 0;
i < req.count;
i++) {
382 struct v4l2_buffer buf = {
383 .type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
385 .memory = V4L2_MEMORY_MMAP
386 };
387 if (
v4l2_ioctl(
s->fd, VIDIOC_QUERYBUF, &buf) < 0) {
390 return res;
391 }
392
393 s->buf_len[
i] = buf.length;
394 if (
s->frame_size > 0 &&
s->buf_len[
i] <
s->frame_size) {
396 "buf_len[%d] = %d < expected frame size %d\n",
397 i,
s->buf_len[
i],
s->frame_size);
399 }
401 PROT_READ | PROT_WRITE, MAP_SHARED,
402 s->fd, buf.m.offset);
403
404 if (
s->buf_start[
i] == MAP_FAILED) {
407 return res;
408 }
409 }
410
411 return 0;
412 }
413
415 {
416 int res = 0;
417
421 } else {
423 }
424
425 return res;
426 }
427
429 {
430 struct v4l2_buffer buf = { 0 };
431 struct buff_data *buf_descriptor = opaque;
433
434 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
435 buf.memory = V4L2_MEMORY_MMAP;
436 buf.index = buf_descriptor->
index;
438
440 }
441
442 #if HAVE_CLOCK_GETTIME && defined(CLOCK_MONOTONIC)
443 static int64_t av_gettime_monotonic(void)
444 {
446 }
447 #endif
448
450 {
452 int64_t now;
453
456 ts <= now + 1 * AV_TIME_BASE && ts >= now - 10 *
AV_TIME_BASE) {
459 return 0;
460 }
461 #if HAVE_CLOCK_GETTIME && defined(CLOCK_MONOTONIC)
463 now = av_gettime_monotonic();
465 (ts <= now + 1 * AV_TIME_BASE && ts >= now - 10 *
AV_TIME_BASE)) {
469 /* microseconds instead of seconds, MHz instead of Hz */
474 return 0;
475 }
476 }
477 #endif
480 }
481
483 {
485
490 }
491 #if HAVE_CLOCK_GETTIME && defined(CLOCK_MONOTONIC)
494 int64_t nowm = av_gettime_monotonic();
496 s->last_time_m = nowm;
498 }
499 #endif
500 return 0;
501 }
502
504 {
506 struct v4l2_buffer buf = {
507 .type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
508 .memory = V4L2_MEMORY_MMAP
509 };
510 struct timeval buf_ts;
511 int res;
512
514
515 /* FIXME: Some special treatment might be needed in case of loss of signal... */
516 while ((res =
v4l2_ioctl(
s->fd, VIDIOC_DQBUF, &buf)) < 0 && (errno == EINTR));
517 if (res < 0) {
518 if (errno == EAGAIN)
520
524 return res;
525 }
526
527 buf_ts = buf.timestamp;
528
529 if (buf.index >=
s->buffers) {
532 }
534 // always keep at least one buffer queued
536
537 #ifdef V4L2_BUF_FLAG_ERROR
538 if (buf.flags & V4L2_BUF_FLAG_ERROR) {
540 "Dequeued v4l2 buffer contains corrupted data (%d bytes).\n",
541 buf.bytesused);
542 buf.bytesused = 0;
543 } else
544 #endif
545 {
546 /* CPIA is a compressed format and we don't know the exact number of bytes
547 * used by a frame, so set it here as the driver announces it. */
549 s->frame_size = buf.bytesused;
550
551 if (
s->frame_size > 0 && buf.bytesused !=
s->frame_size) {
553 "Dequeued v4l2 buffer contains %d bytes, but %d were expected. Flags: 0x%08X.\n",
554 buf.bytesused,
s->frame_size, buf.flags);
555 buf.bytesused = 0;
556 }
557 }
558
559 /* Image is at s->buff_start[buf.index] */
561 /* when we start getting low on queued buffers, fall back on copying data */
563 if (res < 0) {
566 return res;
567 }
568 memcpy(
pkt->
data,
s->buf_start[buf.index], buf.bytesused);
569
571 if (res) {
573 return res;
574 }
575 } else {
577
578 pkt->
data =
s->buf_start[buf.index];
580
582 if (!buf_descriptor) {
583 /* Something went wrong... Since av_malloc() failed, we cannot even
584 * allocate a buffer for memcpying into it
585 */
588
590 }
591 buf_descriptor->
index = buf.index;
592 buf_descriptor->
s =
s;
593
595 buf_descriptor, 0);
601 }
602 }
603 pkt->
pts = buf_ts.tv_sec * INT64_C(1000000) + buf_ts.tv_usec;
605
607 }
608
610 {
612 enum v4l2_buf_type
type;
614
615 for (
i = 0;
i <
s->buffers;
i++) {
616 struct v4l2_buffer buf = {
617 .type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
619 .memory = V4L2_MEMORY_MMAP
620 };
621
626 return res;
627 }
628 }
630
631 type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
636 return res;
637 }
638
639 return 0;
640 }
641
643 {
644 enum v4l2_buf_type
type;
646
647 type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
648 /* We do not check for the result, because we could
649 * not do anything about it anyway...
650 */
652 for (
i = 0;
i <
s->buffers;
i++) {
654 }
657 }
658
660 {
662 struct v4l2_standard standard = { 0 };
663 struct v4l2_streamparm streamparm = { 0 };
664 struct v4l2_fract *tpf;
667
673 }
674
679 /* set tv standard */
682 if (
v4l2_ioctl(
s->fd, VIDIOC_ENUMSTD, &standard) < 0) {
684 break;
685 }
687 break;
688 }
692 }
693
694 if (
v4l2_ioctl(
s->fd, VIDIOC_S_STD, &standard.id) < 0) {
698 }
699 } else {
701 "This device does not support any standard\n");
702 }
703 }
704
705 /* get standard */
707 tpf = &standard.frameperiod;
710 if (
v4l2_ioctl(
s->fd, VIDIOC_ENUMSTD, &standard) < 0) {
713 #ifdef ENODATA
715 #endif
716 ) {
717 tpf = &streamparm.parm.capture.timeperframe;
718 break;
719 }
722 }
723 if (standard.id ==
s->std_id) {
725 "Current standard: %s, id: %"PRIx64", frameperiod: %d/%d\n",
726 standard.name, (uint64_t)standard.id, tpf->numerator, tpf->denominator);
727 break;
728 }
729 }
730 } else {
731 tpf = &streamparm.parm.capture.timeperframe;
732 }
733
734 streamparm.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
735 if (
v4l2_ioctl(
s->fd, VIDIOC_G_PARM, &streamparm) < 0) {
738 }
else if (framerate_q.
num && framerate_q.
den) {
739 if (streamparm.parm.capture.capability & V4L2_CAP_TIMEPERFRAME) {
740 tpf = &streamparm.parm.capture.timeperframe;
741
743 framerate_q.
den, framerate_q.
num);
744 tpf->numerator = framerate_q.
den;
745 tpf->denominator = framerate_q.
num;
746
747 if (
v4l2_ioctl(
s->fd, VIDIOC_S_PARM, &streamparm) < 0) {
752 }
753
754 if (framerate_q.
num != tpf->denominator ||
755 framerate_q.
den != tpf->numerator) {
757 "The driver changed the time per frame from "
758 "%d/%d to %d/%d\n",
759 framerate_q.
den, framerate_q.
num,
760 tpf->numerator, tpf->denominator);
761 }
762 } else {
764 "The driver does not permit changing the time per frame\n");
765 }
766 }
767 if (tpf->denominator > 0 && tpf->numerator > 0) {
771 } else
773
774 return 0;
775 }
776
781 uint32_t *desired_format,
783 {
785
787
788 if (*desired_format) {
791 *desired_format = 0;
794 }
795 }
796
797 if (!*desired_format) {
804
808 break;
811 *desired_format = 0;
812 }
813 }
814
815 if (*desired_format == 0) {
817 "codec '%s' (id %d), pixel format '%s' (id %d)\n",
821 }
822 }
823
828 }
829
831 {
834 return 0;
835 }
836
838 {
841 int res = 0;
842 uint32_t desired_format;
845 struct v4l2_input
input = { 0 };
846
848 if (!st)
850
851 #if CONFIG_LIBV4L2
852 /* silence libv4l2 logging. if fopen() fails v4l2_log_file will be NULL
853 and errors will get sent to stderr */
855 v4l2_log_file = fopen("/dev/null", "w");
856 #endif
857
861
862 if (
s->channel != -1) {
863 /* set video input */
865 if (
v4l2_ioctl(
s->fd, VIDIOC_S_INPUT, &
s->channel) < 0) {
869 }
870 } else {
871 /* get current video input */
872 if (
v4l2_ioctl(
s->fd, VIDIOC_G_INPUT, &
s->channel) < 0) {
876 }
877 }
878
879 /* enum input */
885 }
889
890 if (
s->list_format) {
894 }
895
896 if (
s->list_standard) {
900 }
901
903
904 if (
s->pixel_format) {
906
909
911
915
918 }
919 }
920
921 if (!
s->width && !
s->height) {
922 struct v4l2_format fmt = { .type = V4L2_BUF_TYPE_VIDEO_CAPTURE };
923
925 "Querying the device for the current frame size\n");
931 }
932
933 s->width = fmt.fmt.pix.width;
934 s->height = fmt.fmt.pix.height;
936 "Setting frame size to %dx%d\n",
s->width,
s->height);
937 }
938
940 if (res < 0)
942
943 /* If no pixel_format was specified, the codec_id was not known up
944 * until now. Set video_codec_id in the context, as codec_id will
945 * not be available outside this function
946 */
949
952
953 s->pixelformat = desired_format;
954
957
961 s->width,
s->height, 1);
962
966
968
976 }
977 if (desired_format == V4L2_PIX_FMT_YVU420)
979 else if (desired_format == V4L2_PIX_FMT_YVU410)
985
986 return 0;
987
990 return res;
991 }
992
994 {
995 int res;
996
998 return res;
999 }
1000
1002 }
1003
1005 {
1007
1010 "close.\n");
1011
1013
1015 return 0;
1016 }
1017
1019 {
1020 return !strncmp(
name,
"video", 5) ||
1021 !strncmp(
name,
"radio", 5) ||
1022 !strncmp(
name,
"vbi", 3) ||
1023 !strncmp(
name,
"v4l-subdev", 10);
1024 }
1025
1027 {
1029 DIR *dir;
1030 struct dirent *entry;
1032
1033 if (!device_list)
1035
1036 dir = opendir("/dev");
1037 if (!dir) {
1041 }
1042 while ((entry = readdir(dir))) {
1044 struct v4l2_capability cap;
1046 char device_name[256];
1047
1049 continue;
1050
1051 size =
snprintf(device_name,
sizeof(device_name),
"/dev/%s", entry->d_name);
1052 if (
size >=
sizeof(device_name)) {
1055 break;
1056 }
1057
1059 continue;
1060
1061 if (
v4l2_ioctl(fd, VIDIOC_QUERYCAP, &cap) < 0) {
1065 }
1066
1068 if (!device) {
1071 }
1077 }
1078
1082
1084 continue;
1085
1087 if (device) {
1091 }
1093 break;
1094 }
1095 closedir(dir);
1097 }
1098
1099 #define OFFSET(x) offsetof(struct video_data, x)
1100 #define DEC AV_OPT_FLAG_DECODING_PARAM
1101
1109
1110 {
"list_formats",
"list available formats and exit",
OFFSET(list_format),
AV_OPT_TYPE_INT, {.i64 = 0 }, 0, INT_MAX,
DEC,
"list_formats" },
1114
1115 {
"list_standards",
"list supported standards and exit",
OFFSET(list_standard),
AV_OPT_TYPE_INT, {.i64 = 0 }, 0, 1,
DEC,
"list_standards" },
1116 {
"all",
"show all supported standards",
OFFSET(list_standard),
AV_OPT_TYPE_CONST, {.i64 = 1 }, 0, 0,
DEC,
"list_standards" },
1117
1118 {
"timestamps",
"set type of timestamps for grabbed frames",
OFFSET(ts_mode),
AV_OPT_TYPE_INT, {.i64 = 0 }, 0, 2,
DEC,
"timestamps" },
1119 {
"ts",
"set type of timestamps for grabbed frames",
OFFSET(ts_mode),
AV_OPT_TYPE_INT, {.i64 = 0 }, 0, 2,
DEC,
"timestamps" },
1123 {
"use_libv4l2",
"use libv4l2 (v4l-utils) conversion functions",
OFFSET(use_libv4l2),
AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1,
DEC },
1125 };
1126
1133 };
1134
1136 .
name =
"video4linux2,v4l2",
1146 };