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
34
35 #if CONFIG_LIBV4L2
36 #include <libv4l2.h>
37 #endif
38
40
41 #define V4L_ALLFORMATS 3
42 #define V4L_RAWFORMATS 1
43 #define V4L_COMPFORMATS 2
44
45 /**
46 * Return timestamps to the user exactly as returned by the kernel
47 */
48 #define V4L_TS_DEFAULT 0
49 /**
50 * Autodetect the kind of timestamps returned by the kernel and convert to
51 * absolute (wall clock) timestamps.
52 */
54 /**
55 * Assume kernel timestamps are from the monotonic clock and convert to
56 * absolute timestamps.
57 */
58 #define V4L_TS_MONO2ABS 2
59
60 /**
61 * Once the kind of timestamps returned by the kernel have been detected,
62 * the value of the timefilter (NULL or not) determines whether a conversion
63 * takes place.
64 */
65 #define V4L_TS_CONVERT_READY V4L_TS_DEFAULT
66
78
90
92 int (*
open_f)(
const char *file,
int oflag, ...);
95 int (*
ioctl_f)(
int fd,
unsigned long int request, ...);
99 };
100
104 };
105
107 {
109 struct v4l2_capability cap;
110 int fd;
113
114 #define SET_WRAPPERS(prefix) do { \
115 s->open_f = prefix ## open; \
116 s->close_f = prefix ## close; \
117 s->dup_f = prefix ## dup; \
118 s->ioctl_f = prefix ## ioctl; \
119 s->read_f = prefix ## read; \
120 s->mmap_f = prefix ## mmap; \
121 s->munmap_f = prefix ## munmap; \
122 } while (0)
123
125 #if CONFIG_LIBV4L2
127 #else
130 #endif
131 } else {
133 }
134
135 #define v4l2_open s->open_f
136 #define v4l2_close s->close_f
137 #define v4l2_dup s->dup_f
138 #define v4l2_ioctl s->ioctl_f
139 #define v4l2_read s->read_f
140 #define v4l2_mmap s->mmap_f
141 #define v4l2_munmap s->munmap_f
142
144 flags |= O_NONBLOCK;
145 }
146
148 if (fd < 0) {
153 }
154
155 if (
v4l2_ioctl(fd, VIDIOC_QUERYCAP, &cap) < 0) {
159 goto fail;
160 }
161
163 fd, cap.capabilities);
164
165 if (!(cap.capabilities & V4L2_CAP_VIDEO_CAPTURE)) {
168 goto fail;
169 }
170
171 if (!(cap.capabilities & V4L2_CAP_STREAMING)) {
173 "The device does not support the streaming I/O method.\n");
175 goto fail;
176 }
177
178 return fd;
179
180 fail:
183 }
184
187 {
190 struct v4l2_format fmt = { .type = V4L2_BUF_TYPE_VIDEO_CAPTURE };
191 struct v4l2_pix_format *pix = &fmt.fmt.pix;
192
194
198 pix->field = V4L2_FIELD_ANY;
199
202
203 if ((*width != fmt.fmt.pix.width) || (*height != fmt.fmt.pix.height)) {
205 "The V4L2 driver changed the video from %dx%d to %dx%d\n",
206 *width, *height, fmt.fmt.pix.width, fmt.fmt.pix.height);
207 *width = fmt.fmt.pix.width;
208 *height = fmt.fmt.pix.height;
209 }
210
211 if (pix_fmt != fmt.fmt.pix.pixelformat) {
213 "The V4L2 driver changed the pixel format "
214 "from 0x%08X to 0x%08X\n",
215 pix_fmt, fmt.fmt.pix.pixelformat);
217 }
218
219 if (fmt.fmt.pix.field == V4L2_FIELD_INTERLACED) {
221 "The V4L2 driver is using the interlaced mode\n");
223 }
224
226 }
227
229 {
231 v4l2_std_id std;
232
234 if (res < 0) {
235 return 0;
236 }
237 if (std & V4L2_STD_NTSC) {
238 return 0;
239 }
240
241 return 1;
242 }
243
244 #if HAVE_STRUCT_V4L2_FRMIVALENUM_DISCRETE
245 static void list_framesizes(
AVFormatContext *ctx,
int fd, uint32_t pixelformat)
246 {
248 struct v4l2_frmsizeenum vfse = { .pixel_format = pixelformat };
249
250 while(!
v4l2_ioctl(fd, VIDIOC_ENUM_FRAMESIZES, &vfse)) {
251 switch (vfse.type) {
252 case V4L2_FRMSIZE_TYPE_DISCRETE:
254 vfse.discrete.width, vfse.discrete.height);
255 break;
256 case V4L2_FRMSIZE_TYPE_CONTINUOUS:
257 case V4L2_FRMSIZE_TYPE_STEPWISE:
259 vfse.stepwise.min_width,
260 vfse.stepwise.max_width,
261 vfse.stepwise.step_width,
262 vfse.stepwise.min_height,
263 vfse.stepwise.max_height,
264 vfse.stepwise.step_height);
265 }
266 vfse.index++;
267 }
268 }
269 #endif
270
272 {
274 struct v4l2_fmtdesc vfd = { .type = V4L2_BUF_TYPE_VIDEO_CAPTURE };
275
276 while(!
v4l2_ioctl(fd, VIDIOC_ENUM_FMT, &vfd)) {
279
280 vfd.index++;
281
282 if (!(vfd.flags & V4L2_FMT_FLAG_COMPRESSED) &&
286 fmt_name ? fmt_name : "Unsupported",
287 vfd.description);
288 } else if (vfd.flags & V4L2_FMT_FLAG_COMPRESSED &&
292 codec ? codec->
name :
"Unsupported",
293 vfd.description);
294 } else {
295 continue;
296 }
297
298 #ifdef V4L2_FMT_FLAG_EMULATED
299 if (vfd.flags & V4L2_FMT_FLAG_EMULATED)
301 #endif
302 #if HAVE_STRUCT_V4L2_FRMIVALENUM_DISCRETE
303 list_framesizes(ctx, fd, vfd.pixelformat);
304 #endif
306 }
307 }
308
310 {
313 struct v4l2_standard standard;
314
316 return;
317
318 for (standard.index = 0; ; standard.index++) {
322 break;
323 } else {
325 return;
326 }
327 }
329 standard.index, (uint64_t)standard.id, standard.name);
330 }
331 }
332
334 {
337 struct v4l2_requestbuffers req = {
338 .type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
340 .memory = V4L2_MEMORY_MMAP
341 };
342
347 }
348
349 if (req.count < 2) {
352 }
358 }
364 }
365
366 for (i = 0; i < req.count; i++) {
367 struct v4l2_buffer buf = {
368 .type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
369 .index = i,
370 .memory = V4L2_MEMORY_MMAP
371 };
376 }
377
381 "buf_len[%d] = %d < expected frame size %d\n",
384 }
386 PROT_READ | PROT_WRITE, MAP_SHARED,
387 s->
fd, buf.m.offset);
388
393 }
394 }
395
396 return 0;
397 }
398
399 #if FF_API_DESTRUCT_PACKET
401 {
403 }
404 #endif
405
407 {
408 struct v4l2_buffer buf = { 0 };
410 struct buff_data *buf_descriptor = opaque;
412
413 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
414 buf.memory = V4L2_MEMORY_MMAP;
415 buf.index = buf_descriptor->
index;
417
422 }
423
425 }
426
427 #if HAVE_CLOCK_GETTIME && defined(CLOCK_MONOTONIC)
428 static int64_t av_gettime_monotonic(void)
429 {
430 struct timespec tv;
431
432 clock_gettime(CLOCK_MONOTONIC, &tv);
433 return (int64_t)tv.tv_sec * 1000000 + tv.tv_nsec / 1000;
434 }
435 #endif
436
438 {
440 int64_t now;
441
444 ts <= now + 1 * AV_TIME_BASE && ts >= now - 10 *
AV_TIME_BASE) {
447 return 0;
448 }
449 #if HAVE_CLOCK_GETTIME && defined(CLOCK_MONOTONIC)
451 now = av_gettime_monotonic();
453 (ts <= now + 1 * AV_TIME_BASE && ts >= now - 10 *
AV_TIME_BASE)) {
457 /* microseconds instead of seconds, MHz instead of Hz */
462 return 0;
463 }
464 }
465 #endif
468 }
469
471 {
473
476 if (r < 0)
478 }
479 #if HAVE_CLOCK_GETTIME && defined(CLOCK_MONOTONIC)
482 int64_t nowm = av_gettime_monotonic();
486 }
487 #endif
488 return 0;
489 }
490
492 {
494 struct v4l2_buffer buf = {
495 .type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
496 .memory = V4L2_MEMORY_MMAP
497 };
499
500 /* FIXME: Some special treatment might be needed in case of loss of signal... */
501 while ((res =
v4l2_ioctl(s->
fd, VIDIOC_DQBUF, &buf)) < 0 && (errno == EINTR));
502 if (res < 0) {
503 if (errno == EAGAIN) {
506 }
510 }
511
515 }
517 // always keep at least one buffer queued
519
520 /* CPIA is a compressed format and we don't know the exact number of bytes
521 * used by a frame, so set it here as the driver announces it.
522 */
525
528 "The v4l2 frame is %d bytes, but %d bytes are expected\n",
531 }
532
533 /* Image is at s->buff_start[buf.index] */
535 /* when we start getting low on queued buffers, fall back on copying data */
537 if (res < 0) {
542 }
544
550 }
552 } else {
554
556 pkt->
size = buf.bytesused;
557 #if FF_API_DESTRUCT_PACKET
559 pkt->
destruct = dummy_release_buffer;
561 #endif
562
564 if (buf_descriptor == NULL) {
565 /* Something went wrong... Since av_malloc() failed, we cannot even
566 * allocate a buffer for memcpying into it
567 */
571
573 }
574 buf_descriptor->index = buf.index;
575 buf_descriptor->s =
s;
576
578 buf_descriptor, 0);
585 }
586 }
587 pkt->
pts = buf.timestamp.tv_sec * INT64_C(1000000) + buf.timestamp.tv_usec;
589
591 }
592
594 {
596 enum v4l2_buf_type
type;
598
599 for (i = 0; i < s->
buffers; i++) {
600 struct v4l2_buffer buf = {
601 .type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
602 .index = i,
603 .memory = V4L2_MEMORY_MMAP
604 };
605
610 }
611 }
613
614 type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
619 }
620
621 return 0;
622 }
623
625 {
626 enum v4l2_buf_type
type;
627 int i;
628
629 type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
630 /* We do not check for the result, because we could
631 * not do anything about it anyway...
632 */
634 for (i = 0; i < s->
buffers; i++) {
636 }
639 }
640
642 {
644 struct v4l2_standard standard = { 0 };
645 struct v4l2_streamparm streamparm = { 0 };
646 struct v4l2_fract *tpf;
649
655 }
656
659 ret = 0;
661 /* set tv standard */
662 for (i = 0; ; i++) {
663 standard.index = i;
666 break;
667 }
669 break;
670 }
671 if (ret < 0) {
674 }
675
676 if (
v4l2_ioctl(s->
fd, VIDIOC_S_STD, &standard.id) < 0) {
680 }
681 } else {
683 "This device does not support any standard\n");
684 }
685 }
686
687 /* get standard */
689 tpf = &standard.frameperiod;
690 for (i = 0; ; i++) {
691 standard.index = i;
695 tpf = &streamparm.parm.capture.timeperframe;
696 break;
697 }
700 }
701 if (standard.id == s->
std_id) {
703 "Current standard: %s, id: %"PRIx64", frameperiod: %d/%d\n",
704 standard.name, (uint64_t)standard.id, tpf->numerator, tpf->denominator);
705 break;
706 }
707 }
708 } else {
709 tpf = &streamparm.parm.capture.timeperframe;
710 }
711
712 streamparm.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
713 if (
v4l2_ioctl(s->
fd, VIDIOC_G_PARM, &streamparm) < 0) {
717 }
718
719 if (framerate_q.
num && framerate_q.
den) {
720 if (streamparm.parm.capture.capability & V4L2_CAP_TIMEPERFRAME) {
721 tpf = &streamparm.parm.capture.timeperframe;
722
724 framerate_q.
den, framerate_q.
num);
725 tpf->numerator = framerate_q.
den;
726 tpf->denominator = framerate_q.
num;
727
728 if (
v4l2_ioctl(s->
fd, VIDIOC_S_PARM, &streamparm) < 0) {
732 }
733
734 if (framerate_q.
num != tpf->denominator ||
735 framerate_q.
den != tpf->numerator) {
737 "The driver changed the time per frame from "
738 "%d/%d to %d/%d\n",
739 framerate_q.
den, framerate_q.
num,
740 tpf->numerator, tpf->denominator);
741 }
742 } else {
744 "The driver does not allow to change time per frame\n");
745 }
746 }
747 if (tpf->denominator > 0 && tpf->numerator > 0) {
751 } else
753
754 return 0;
755 }
756
761 uint32_t *desired_format,
763 {
765
767
768 if (*desired_format) {
769 ret =
device_init(s1, width, height, *desired_format);
770 if (ret < 0) {
771 *desired_format = 0;
774 }
775 }
776
777 if (!*desired_format) {
784
786 ret =
device_init(s1, width, height, *desired_format);
787 if (ret >= 0)
788 break;
789 else if (ret !=
AVERROR(EINVAL))
791 *desired_format = 0;
792 }
793 }
794
795 if (*desired_format == 0) {
797 "codec '%s' (id %d), pixel format '%s' (id %d)\n",
801 }
802 }
803
807 }
808
810 {
814 uint32_t desired_format;
817 struct v4l2_input input = { 0 };
818
820 if (!st)
822
823 #if CONFIG_LIBV4L2
824 /* silence libv4l2 logging. if fopen() fails v4l2_log_file will be NULL
825 and errors will get sent to stderr */
827 v4l2_log_file = fopen("/dev/null", "w");
828 #endif
829
833
835 /* set video input */
841 }
842 } else {
843 /* get current video input */
848 }
849 }
850
851 /* enum input */
857 }
859 av_log(s1,
AV_LOG_DEBUG,
"Current input_channel: %d, input_name: %s, input_std: %"PRIx64
"\n",
860 s->
channel, input.name, (uint64_t)input.std);
861
865 }
866
870 }
871
873
876
879
880 if (codec)
882
884
888
890 }
891 }
892
894 struct v4l2_format fmt = { .type = V4L2_BUF_TYPE_VIDEO_CAPTURE };
895
897 "Querying the device for the current frame size\n");
902 }
903
904 s->
width = fmt.fmt.pix.width;
905 s->
height = fmt.fmt.pix.height;
907 "Setting frame size to %dx%d\n", s->
width, s->
height);
908 }
909
911 if (res < 0) {
914 }
915
916 /* If no pixel_format was specified, the codec_id was not known up
917 * until now. Set video_codec_id in the context, as codec_id will
918 * not be available outside this function
919 */
922
925
927
931
936 }
937
939
947 }
948 if (desired_format == V4L2_PIX_FMT_YVU420)
950 else if (desired_format == V4L2_PIX_FMT_YVU410)
956
957 return 0;
958 }
959
961 {
965
969 }
970
974 }
975
977 }
978
980 {
982
985 "close.\n");
986
988
990 return 0;
991 }
992
993 #define OFFSET(x) offsetof(struct video_data, x)
994 #define DEC AV_OPT_FLAG_DECODING_PARAM
995
1003
1008
1011
1018 { NULL },
1019 };
1020
1026 };
1027
1029 .
name =
"video4linux2,v4l2",
1037 };