2 * Video4Linux2 grab interface
3 * Copyright (c) 2000,2001 Fabrice Bellard
4 * Copyright (c) 2006 Luca Abeni
6 * Part of this file is based on the V4L2 video capture example
7 * (http://v4l2spec.bytesex.org/v4l2spec/capture.c)
9 * Thanks to Michael Niedermayer for providing the mapping between
10 * V4L2_PIX_FMT_* and PIX_FMT_*
13 * This file is part of FFmpeg.
15 * FFmpeg is free software; you can redistribute it and/or
16 * modify it under the terms of the GNU Lesser General Public
17 * License as published by the Free Software Foundation; either
18 * version 2.1 of the License, or (at your option) any later version.
20 * FFmpeg is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
23 * Lesser General Public License for more details.
25 * You should have received a copy of the GNU Lesser General Public
26 * License along with FFmpeg; if not, write to the Free Software
27 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
30 #undef __STRICT_ANSI__ //workaround due to broken kernel headers
32 #include "libavformat/avformat.h"
35 #include <sys/ioctl.h>
38 #if HAVE_SYS_VIDEOIO_H
39 #include <sys/videoio.h>
41 #include <asm/types.h>
42 #include <linux/videodev2.h>
47 static const int desired_video_buffers
= 256;
57 int frame_format
; /* V4L2_PIX_FMT_* */
58 enum io_method io_method
;
65 unsigned int *buf_len
;
74 enum PixelFormat ff_fmt
;
75 enum CodecID codec_id
;
79 static struct fmt_map fmt_conversion_table
[] = {
81 .ff_fmt
= PIX_FMT_YUV420P
,
82 .codec_id
= CODEC_ID_RAWVIDEO
,
83 .v4l2_fmt
= V4L2_PIX_FMT_YUV420
,
86 .ff_fmt
= PIX_FMT_YUV422P
,
87 .codec_id
= CODEC_ID_RAWVIDEO
,
88 .v4l2_fmt
= V4L2_PIX_FMT_YUV422P
,
91 .ff_fmt
= PIX_FMT_YUYV422
,
92 .codec_id
= CODEC_ID_RAWVIDEO
,
93 .v4l2_fmt
= V4L2_PIX_FMT_YUYV
,
96 .ff_fmt
= PIX_FMT_UYVY422
,
97 .codec_id
= CODEC_ID_RAWVIDEO
,
98 .v4l2_fmt
= V4L2_PIX_FMT_UYVY
,
101 .ff_fmt
= PIX_FMT_YUV411P
,
102 .codec_id
= CODEC_ID_RAWVIDEO
,
103 .v4l2_fmt
= V4L2_PIX_FMT_YUV411P
,
106 .ff_fmt
= PIX_FMT_YUV410P
,
107 .codec_id
= CODEC_ID_RAWVIDEO
,
108 .v4l2_fmt
= V4L2_PIX_FMT_YUV410
,
111 .ff_fmt
= PIX_FMT_RGB555
,
112 .codec_id
= CODEC_ID_RAWVIDEO
,
113 .v4l2_fmt
= V4L2_PIX_FMT_RGB555
,
116 .ff_fmt
= PIX_FMT_RGB565
,
117 .codec_id
= CODEC_ID_RAWVIDEO
,
118 .v4l2_fmt
= V4L2_PIX_FMT_RGB565
,
121 .ff_fmt
= PIX_FMT_BGR24
,
122 .codec_id
= CODEC_ID_RAWVIDEO
,
123 .v4l2_fmt
= V4L2_PIX_FMT_BGR24
,
126 .ff_fmt
= PIX_FMT_RGB24
,
127 .codec_id
= CODEC_ID_RAWVIDEO
,
128 .v4l2_fmt
= V4L2_PIX_FMT_RGB24
,
131 .ff_fmt
= PIX_FMT_BGRA
,
132 .codec_id
= CODEC_ID_RAWVIDEO
,
133 .v4l2_fmt
= V4L2_PIX_FMT_BGR32
,
136 .ff_fmt
= PIX_FMT_GRAY8
,
137 .codec_id
= CODEC_ID_RAWVIDEO
,
138 .v4l2_fmt
= V4L2_PIX_FMT_GREY
,
141 .ff_fmt
= PIX_FMT_NONE
,
142 .codec_id
= CODEC_ID_MJPEG
,
143 .v4l2_fmt
= V4L2_PIX_FMT_MJPEG
,
146 .ff_fmt
= PIX_FMT_NONE
,
147 .codec_id
= CODEC_ID_MJPEG
,
148 .v4l2_fmt
= V4L2_PIX_FMT_JPEG
,
152 static int device_open(AVFormatContext
*ctx
, uint32_t *capabilities
)
154 struct v4l2_capability cap
;
159 if (ctx
->flags
& AVFMT_FLAG_NONBLOCK
) {
162 fd
= open(ctx
->filename
, flags
, 0);
164 av_log(ctx
, AV_LOG_ERROR
, "Cannot open video device %s : %s\n",
165 ctx
->filename
, strerror(errno
));
170 res
= ioctl(fd
, VIDIOC_QUERYCAP
, &cap
);
171 // ENOIOCTLCMD definition only availble on __KERNEL__
172 if (res
< 0 && errno
== 515)
174 av_log(ctx
, AV_LOG_ERROR
, "QUERYCAP not implemented, probably V4L device but not supporting V4L2\n");
180 av_log(ctx
, AV_LOG_ERROR
, "ioctl(VIDIOC_QUERYCAP): %s\n",
186 if ((cap
.capabilities
& V4L2_CAP_VIDEO_CAPTURE
) == 0) {
187 av_log(ctx
, AV_LOG_ERROR
, "Not a video capture device\n");
192 *capabilities
= cap
.capabilities
;
197 static int device_init(AVFormatContext
*ctx
, int *width
, int *height
, uint32_t pix_fmt
)
199 struct video_data
*s
= ctx
->priv_data
;
201 struct v4l2_format fmt
;
204 memset(&fmt
, 0, sizeof(struct v4l2_format
));
205 fmt
.type
= V4L2_BUF_TYPE_VIDEO_CAPTURE
;
206 fmt
.fmt
.pix
.width
= *width
;
207 fmt
.fmt
.pix
.height
= *height
;
208 fmt
.fmt
.pix
.pixelformat
= pix_fmt
;
209 fmt
.fmt
.pix
.field
= V4L2_FIELD_INTERLACED
;
210 res
= ioctl(fd
, VIDIOC_S_FMT
, &fmt
);
211 if ((*width
!= fmt
.fmt
.pix
.width
) || (*height
!= fmt
.fmt
.pix
.height
)) {
212 av_log(ctx
, AV_LOG_INFO
, "The V4L2 driver changed the video from %dx%d to %dx%d\n", *width
, *height
, fmt
.fmt
.pix
.width
, fmt
.fmt
.pix
.height
);
213 *width
= fmt
.fmt
.pix
.width
;
214 *height
= fmt
.fmt
.pix
.height
;
217 if (pix_fmt
!= fmt
.fmt
.pix
.pixelformat
) {
218 av_log(ctx
, AV_LOG_DEBUG
, "The V4L2 driver changed the pixel format from 0x%08X to 0x%08X\n", pix_fmt
, fmt
.fmt
.pix
.pixelformat
);
225 static int first_field(int fd
)
230 res
= ioctl(fd
, VIDIOC_G_STD
, &std
);
234 if (std
& V4L2_STD_NTSC
) {
241 static uint32_t fmt_ff2v4l(enum PixelFormat pix_fmt
, enum CodecID codec_id
)
245 for (i
= 0; i
< FF_ARRAY_ELEMS(fmt_conversion_table
); i
++) {
246 if ((codec_id
== CODEC_ID_NONE
||
247 fmt_conversion_table
[i
].codec_id
== codec_id
) &&
248 (pix_fmt
== PIX_FMT_NONE
||
249 fmt_conversion_table
[i
].ff_fmt
== pix_fmt
)) {
250 return fmt_conversion_table
[i
].v4l2_fmt
;
257 static enum PixelFormat
fmt_v4l2ff(uint32_t v4l2_fmt
, enum CodecID codec_id
)
261 for (i
= 0; i
< FF_ARRAY_ELEMS(fmt_conversion_table
); i
++) {
262 if (fmt_conversion_table
[i
].v4l2_fmt
== v4l2_fmt
&&
263 fmt_conversion_table
[i
].codec_id
== codec_id
) {
264 return fmt_conversion_table
[i
].ff_fmt
;
271 static enum CodecID
fmt_v4l2codec(uint32_t v4l2_fmt
)
275 for (i
= 0; i
< FF_ARRAY_ELEMS(fmt_conversion_table
); i
++) {
276 if (fmt_conversion_table
[i
].v4l2_fmt
== v4l2_fmt
) {
277 return fmt_conversion_table
[i
].codec_id
;
281 return CODEC_ID_NONE
;
284 static int mmap_init(AVFormatContext
*ctx
)
286 struct video_data
*s
= ctx
->priv_data
;
287 struct v4l2_requestbuffers req
;
290 memset(&req
, 0, sizeof(struct v4l2_requestbuffers
));
291 req
.count
= desired_video_buffers
;
292 req
.type
= V4L2_BUF_TYPE_VIDEO_CAPTURE
;
293 req
.memory
= V4L2_MEMORY_MMAP
;
294 res
= ioctl (s
->fd
, VIDIOC_REQBUFS
, &req
);
296 if (errno
== EINVAL
) {
297 av_log(ctx
, AV_LOG_ERROR
, "Device does not support mmap\n");
299 av_log(ctx
, AV_LOG_ERROR
, "ioctl(VIDIOC_REQBUFS)\n");
306 av_log(ctx
, AV_LOG_ERROR
, "Insufficient buffer memory\n");
310 s
->buffers
= req
.count
;
311 s
->buf_start
= av_malloc(sizeof(void *) * s
->buffers
);
312 if (s
->buf_start
== NULL
) {
313 av_log(ctx
, AV_LOG_ERROR
, "Cannot allocate buffer pointers\n");
317 s
->buf_len
= av_malloc(sizeof(unsigned int) * s
->buffers
);
318 if (s
->buf_len
== NULL
) {
319 av_log(ctx
, AV_LOG_ERROR
, "Cannot allocate buffer sizes\n");
320 av_free(s
->buf_start
);
325 for (i
= 0; i
< req
.count
; i
++) {
326 struct v4l2_buffer buf
;
328 memset(&buf
, 0, sizeof(struct v4l2_buffer
));
329 buf
.type
= V4L2_BUF_TYPE_VIDEO_CAPTURE
;
330 buf
.memory
= V4L2_MEMORY_MMAP
;
332 res
= ioctl (s
->fd
, VIDIOC_QUERYBUF
, &buf
);
334 av_log(ctx
, AV_LOG_ERROR
, "ioctl(VIDIOC_QUERYBUF)\n");
339 s
->buf_len
[i
] = buf
.length
;
340 if (s
->frame_size
> 0 && s
->buf_len
[i
] < s
->frame_size
) {
341 av_log(ctx
, AV_LOG_ERROR
, "Buffer len [%d] = %d != %d\n", i
, s
->buf_len
[i
], s
->frame_size
);
345 s
->buf_start
[i
] = mmap (NULL
, buf
.length
,
346 PROT_READ
| PROT_WRITE
, MAP_SHARED
, s
->fd
, buf
.m
.offset
);
347 if (s
->buf_start
[i
] == MAP_FAILED
) {
348 av_log(ctx
, AV_LOG_ERROR
, "mmap: %s\n", strerror(errno
));
357 static int read_init(AVFormatContext
*ctx
)
362 static void mmap_release_buffer(AVPacket
*pkt
)
364 struct v4l2_buffer buf
;
366 struct buff_data
*buf_descriptor
= pkt
->priv
;
368 if (pkt
->data
== NULL
) {
372 memset(&buf
, 0, sizeof(struct v4l2_buffer
));
373 buf
.type
= V4L2_BUF_TYPE_VIDEO_CAPTURE
;
374 buf
.memory
= V4L2_MEMORY_MMAP
;
375 buf
.index
= buf_descriptor
->index
;
376 fd
= buf_descriptor
->fd
;
377 av_free(buf_descriptor
);
379 res
= ioctl (fd
, VIDIOC_QBUF
, &buf
);
381 av_log(NULL
, AV_LOG_ERROR
, "ioctl(VIDIOC_QBUF)\n");
387 static int mmap_read_frame(AVFormatContext
*ctx
, AVPacket
*pkt
)
389 struct video_data
*s
= ctx
->priv_data
;
390 struct v4l2_buffer buf
;
391 struct buff_data
*buf_descriptor
;
394 memset(&buf
, 0, sizeof(struct v4l2_buffer
));
395 buf
.type
= V4L2_BUF_TYPE_VIDEO_CAPTURE
;
396 buf
.memory
= V4L2_MEMORY_MMAP
;
398 /* FIXME: Some special treatment might be needed in case of loss of signal... */
399 while ((res
= ioctl(s
->fd
, VIDIOC_DQBUF
, &buf
)) < 0 && (errno
== EINTR
));
401 if (errno
== EAGAIN
) {
404 return AVERROR(EAGAIN
);
406 av_log(ctx
, AV_LOG_ERROR
, "ioctl(VIDIOC_DQBUF): %s\n", strerror(errno
));
410 assert (buf
.index
< s
->buffers
);
411 if (s
->frame_size
> 0 && buf
.bytesused
!= s
->frame_size
) {
412 av_log(ctx
, AV_LOG_ERROR
, "The v4l2 frame is %d bytes, but %d bytes are expected\n", buf
.bytesused
, s
->frame_size
);
417 /* Image is at s->buff_start[buf.index] */
418 pkt
->data
= s
->buf_start
[buf
.index
];
419 pkt
->size
= buf
.bytesused
;
420 pkt
->pts
= buf
.timestamp
.tv_sec
* INT64_C(1000000) + buf
.timestamp
.tv_usec
;
421 pkt
->destruct
= mmap_release_buffer
;
422 buf_descriptor
= av_malloc(sizeof(struct buff_data
));
423 if (buf_descriptor
== NULL
) {
424 /* Something went wrong... Since av_malloc() failed, we cannot even
425 * allocate a buffer for memcopying into it
427 av_log(ctx
, AV_LOG_ERROR
, "Failed to allocate a buffer descriptor\n");
428 res
= ioctl (s
->fd
, VIDIOC_QBUF
, &buf
);
432 buf_descriptor
->fd
= s
->fd
;
433 buf_descriptor
->index
= buf
.index
;
434 pkt
->priv
= buf_descriptor
;
436 return s
->buf_len
[buf
.index
];
439 static int read_frame(AVFormatContext
*ctx
, AVPacket
*pkt
)
444 static int mmap_start(AVFormatContext
*ctx
)
446 struct video_data
*s
= ctx
->priv_data
;
447 enum v4l2_buf_type type
;
450 for (i
= 0; i
< s
->buffers
; i
++) {
451 struct v4l2_buffer buf
;
453 memset(&buf
, 0, sizeof(struct v4l2_buffer
));
454 buf
.type
= V4L2_BUF_TYPE_VIDEO_CAPTURE
;
455 buf
.memory
= V4L2_MEMORY_MMAP
;
458 res
= ioctl (s
->fd
, VIDIOC_QBUF
, &buf
);
460 av_log(ctx
, AV_LOG_ERROR
, "ioctl(VIDIOC_QBUF): %s\n", strerror(errno
));
466 type
= V4L2_BUF_TYPE_VIDEO_CAPTURE
;
467 res
= ioctl (s
->fd
, VIDIOC_STREAMON
, &type
);
469 av_log(ctx
, AV_LOG_ERROR
, "ioctl(VIDIOC_STREAMON): %s\n", strerror(errno
));
477 static void mmap_close(struct video_data
*s
)
479 enum v4l2_buf_type type
;
482 type
= V4L2_BUF_TYPE_VIDEO_CAPTURE
;
483 /* We do not check for the result, because we could
484 * not do anything about it anyway...
486 ioctl(s
->fd
, VIDIOC_STREAMOFF
, &type
);
487 for (i
= 0; i
< s
->buffers
; i
++) {
488 munmap(s
->buf_start
[i
], s
->buf_len
[i
]);
490 av_free(s
->buf_start
);
494 static int v4l2_set_parameters( AVFormatContext
*s1
, AVFormatParameters
*ap
)
496 struct video_data
*s
= s1
->priv_data
;
497 struct v4l2_input input
;
498 struct v4l2_standard standard
;
502 /* set tv video input */
503 memset (&input
, 0, sizeof (input
));
504 input
.index
= ap
->channel
;
505 if(ioctl (s
->fd
, VIDIOC_ENUMINPUT
, &input
) < 0) {
506 av_log(s1
, AV_LOG_ERROR
, "The V4L2 driver ioctl enum input failed:\n");
510 av_log(s1
, AV_LOG_DEBUG
, "The V4L2 driver set input_id: %d, input: %s\n",
511 ap
->channel
, input
.name
);
512 if(ioctl (s
->fd
, VIDIOC_S_INPUT
, &input
.index
) < 0 ) {
513 av_log(s1
, AV_LOG_ERROR
, "The V4L2 driver ioctl set input(%d) failed\n",
520 av_log(s1
, AV_LOG_DEBUG
, "The V4L2 driver set standard: %s\n",
522 /* set tv standard */
523 memset (&standard
, 0, sizeof (standard
));
526 if (ioctl(s
->fd
, VIDIOC_ENUMSTD
, &standard
) < 0) {
527 av_log(s1
, AV_LOG_ERROR
, "The V4L2 driver ioctl set standard(%s) failed\n",
532 if(!strcasecmp(standard
.name
, ap
->standard
)) {
537 av_log(s1
, AV_LOG_DEBUG
, "The V4L2 driver set standard: %s, id: %"PRIu64
"\n",
538 ap
->standard
, (uint64_t)standard
.id
);
539 if (ioctl(s
->fd
, VIDIOC_S_STD
, &standard
.id
) < 0) {
540 av_log(s1
, AV_LOG_ERROR
, "The V4L2 driver ioctl set standard(%s) failed\n",
549 static uint32_t device_try_init(AVFormatContext
*s1
,
550 const AVFormatParameters
*ap
,
553 enum CodecID
*codec_id
)
555 uint32_t desired_format
= fmt_ff2v4l(ap
->pix_fmt
, ap
->video_codec_id
);
557 if (desired_format
== 0 ||
558 device_init(s1
, width
, height
, desired_format
) < 0) {
562 for (i
= 0; i
<FF_ARRAY_ELEMS(fmt_conversion_table
); i
++) {
563 if (ap
->video_codec_id
== CODEC_ID_NONE
||
564 fmt_conversion_table
[i
].codec_id
== ap
->video_codec_id
) {
565 desired_format
= fmt_conversion_table
[i
].v4l2_fmt
;
566 if (device_init(s1
, width
, height
, desired_format
) >= 0) {
573 if (desired_format
!= 0) {
574 *codec_id
= fmt_v4l2codec(desired_format
);
575 assert(*codec_id
!= CODEC_ID_NONE
);
578 return desired_format
;
581 static int v4l2_read_header(AVFormatContext
*s1
, AVFormatParameters
*ap
)
583 struct video_data
*s
= s1
->priv_data
;
587 uint32_t desired_format
, capabilities
;
588 enum CodecID codec_id
;
590 if (ap
->width
<= 0 || ap
->height
<= 0) {
591 av_log(s1
, AV_LOG_ERROR
, "Wrong size (%dx%d)\n", ap
->width
, ap
->height
);
598 if(avcodec_check_dimensions(s1
, ap
->width
, ap
->height
) < 0)
601 st
= av_new_stream(s1
, 0);
603 return AVERROR(ENOMEM
);
605 av_set_pts_info(st
, 64, 1, 1000000); /* 64 bits pts in us */
611 s
->fd
= device_open(s1
, &capabilities
);
615 av_log(s1
, AV_LOG_INFO
, "[%d]Capabilities: %x\n", s
->fd
, capabilities
);
617 desired_format
= device_try_init(s1
, ap
, &width
, &height
, &codec_id
);
618 if (desired_format
== 0) {
619 av_log(s1
, AV_LOG_ERROR
, "Cannot find a proper format for "
620 "codec_id %d, pix_fmt %d.\n", ap
->video_codec_id
, ap
->pix_fmt
);
625 s
->frame_format
= desired_format
;
627 if( v4l2_set_parameters( s1
, ap
) < 0 )
630 st
->codec
->pix_fmt
= fmt_v4l2ff(desired_format
, codec_id
);
631 s
->frame_size
= avpicture_get_size(st
->codec
->pix_fmt
, width
, height
);
632 if (capabilities
& V4L2_CAP_STREAMING
) {
633 s
->io_method
= io_mmap
;
636 res
= mmap_start(s1
);
639 s
->io_method
= io_read
;
647 s
->top_field_first
= first_field(s
->fd
);
649 st
->codec
->codec_type
= CODEC_TYPE_VIDEO
;
650 st
->codec
->codec_id
= codec_id
;
651 st
->codec
->width
= width
;
652 st
->codec
->height
= height
;
653 st
->codec
->time_base
.den
= ap
->time_base
.den
;
654 st
->codec
->time_base
.num
= ap
->time_base
.num
;
655 st
->codec
->bit_rate
= s
->frame_size
* 1/av_q2d(st
->codec
->time_base
) * 8;
660 static int v4l2_read_packet(AVFormatContext
*s1
, AVPacket
*pkt
)
662 struct video_data
*s
= s1
->priv_data
;
665 if (s
->io_method
== io_mmap
) {
667 res
= mmap_read_frame(s1
, pkt
);
668 } else if (s
->io_method
== io_read
) {
669 if (av_new_packet(pkt
, s
->frame_size
) < 0)
672 res
= read_frame(s1
, pkt
);
680 if (s1
->streams
[0]->codec
->coded_frame
) {
681 s1
->streams
[0]->codec
->coded_frame
->interlaced_frame
= 1;
682 s1
->streams
[0]->codec
->coded_frame
->top_field_first
= s
->top_field_first
;
688 static int v4l2_read_close(AVFormatContext
*s1
)
690 struct video_data
*s
= s1
->priv_data
;
692 if (s
->io_method
== io_mmap
) {
700 AVInputFormat v4l2_demuxer
= {
702 NULL_IF_CONFIG_SMALL("Video4Linux2 device grab"),
703 sizeof(struct video_data
),
708 .flags
= AVFMT_NOFILE
,