]> rtime.felk.cvut.cz Git - frescor/ffmpeg.git/blob - libavdevice/v4l2.c
818366a71547cb2c5c0fe85cdcf7e8cdbe573222
[frescor/ffmpeg.git] / libavdevice / v4l2.c
1 /*
2  * Video4Linux2 grab interface
3  * Copyright (c) 2000,2001 Fabrice Bellard.
4  * Copyright (c) 2006 Luca Abeni.
5  *
6  * Part of this file is based on the V4L2 video capture example
7  * (http://v4l2spec.bytesex.org/v4l2spec/capture.c)
8  *
9  * Thanks to Michael Niedermayer for providing the mapping between
10  * V4L2_PIX_FMT_* and PIX_FMT_*
11  *
12  *
13  * This file is part of FFmpeg.
14  *
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.
19  *
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.
24  *
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
28  */
29
30 #undef __STRICT_ANSI__ //workaround due to broken kernel headers
31 #include "config.h"
32 #include "libavformat/avformat.h"
33 #include <unistd.h>
34 #include <fcntl.h>
35 #include <sys/ioctl.h>
36 #include <sys/mman.h>
37 #include <sys/time.h>
38 #include <asm/types.h>
39 #include <linux/videodev2.h>
40 #include <time.h>
41 #include <strings.h>
42
43 static const int desired_video_buffers = 256;
44
45 enum io_method {
46     io_read,
47     io_mmap,
48     io_userptr
49 };
50
51 struct video_data {
52     int fd;
53     int frame_format; /* V4L2_PIX_FMT_* */
54     enum io_method io_method;
55     int width, height;
56     int frame_rate;
57     int frame_rate_base;
58     int frame_size;
59     int top_field_first;
60
61     int buffers;
62     void **buf_start;
63     unsigned int *buf_len;
64 };
65
66 struct buff_data {
67     int index;
68     int fd;
69 };
70
71 struct fmt_map {
72     enum PixelFormat ff_fmt;
73     int32_t v4l2_fmt;
74 };
75
76 static struct fmt_map fmt_conversion_table[] = {
77     {
78         .ff_fmt = PIX_FMT_YUV420P,
79         .v4l2_fmt = V4L2_PIX_FMT_YUV420,
80     },
81     {
82         .ff_fmt = PIX_FMT_YUV422P,
83         .v4l2_fmt = V4L2_PIX_FMT_YUV422P,
84     },
85     {
86         .ff_fmt = PIX_FMT_YUYV422,
87         .v4l2_fmt = V4L2_PIX_FMT_YUYV,
88     },
89     {
90         .ff_fmt = PIX_FMT_UYVY422,
91         .v4l2_fmt = V4L2_PIX_FMT_UYVY,
92     },
93     {
94         .ff_fmt = PIX_FMT_YUV411P,
95         .v4l2_fmt = V4L2_PIX_FMT_YUV411P,
96     },
97     {
98         .ff_fmt = PIX_FMT_YUV410P,
99         .v4l2_fmt = V4L2_PIX_FMT_YUV410,
100     },
101     {
102         .ff_fmt = PIX_FMT_BGR24,
103         .v4l2_fmt = V4L2_PIX_FMT_BGR24,
104     },
105     {
106         .ff_fmt = PIX_FMT_RGB24,
107         .v4l2_fmt = V4L2_PIX_FMT_RGB24,
108     },
109     /*
110     {
111         .ff_fmt = PIX_FMT_RGB32,
112         .v4l2_fmt = V4L2_PIX_FMT_BGR32,
113     },
114     */
115     {
116         .ff_fmt = PIX_FMT_GRAY8,
117         .v4l2_fmt = V4L2_PIX_FMT_GREY,
118     },
119 };
120
121 static int device_open(AVFormatContext *ctx, uint32_t *capabilities)
122 {
123     struct v4l2_capability cap;
124     int fd;
125     int res;
126     int flags = O_RDWR;
127
128     if (ctx->flags & AVFMT_FLAG_NONBLOCK) {
129         flags |= O_NONBLOCK;
130     }
131     fd = open(ctx->filename, flags, 0);
132     if (fd < 0) {
133         av_log(ctx, AV_LOG_ERROR, "Cannot open video device %s : %s\n",
134                  ctx->filename, strerror(errno));
135
136         return -1;
137     }
138
139     res = ioctl(fd, VIDIOC_QUERYCAP, &cap);
140     // ENOIOCTLCMD definition only availble on __KERNEL__
141     if (res < 0 && errno == 515)
142     {
143         av_log(ctx, AV_LOG_ERROR, "QUERYCAP not implemented, probably V4L device but not supporting V4L2\n");
144         close(fd);
145
146         return -1;
147     }
148     if (res < 0) {
149         av_log(ctx, AV_LOG_ERROR, "ioctl(VIDIOC_QUERYCAP): %s\n",
150                  strerror(errno));
151         close(fd);
152
153         return -1;
154     }
155     if ((cap.capabilities & V4L2_CAP_VIDEO_CAPTURE) == 0) {
156         av_log(ctx, AV_LOG_ERROR, "Not a video capture device\n");
157         close(fd);
158
159         return -1;
160     }
161     *capabilities = cap.capabilities;
162
163     return fd;
164 }
165
166 static int device_init(AVFormatContext *ctx, int *width, int *height, int pix_fmt)
167 {
168     struct video_data *s = ctx->priv_data;
169     int fd = s->fd;
170     struct v4l2_format fmt;
171     int res;
172
173     memset(&fmt, 0, sizeof(struct v4l2_format));
174     fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
175     fmt.fmt.pix.width = *width;
176     fmt.fmt.pix.height = *height;
177     fmt.fmt.pix.pixelformat = pix_fmt;
178     fmt.fmt.pix.field = V4L2_FIELD_INTERLACED;
179     res = ioctl(fd, VIDIOC_S_FMT, &fmt);
180     if ((*width != fmt.fmt.pix.width) || (*height != fmt.fmt.pix.height)) {
181         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);
182         *width = fmt.fmt.pix.width;
183         *height = fmt.fmt.pix.height;
184     }
185
186     return res;
187 }
188
189 static int first_field(int fd)
190 {
191     int res;
192     v4l2_std_id std;
193
194     res = ioctl(fd, VIDIOC_G_STD, &std);
195     if (res < 0) {
196         return 0;
197     }
198     if (std & V4L2_STD_NTSC) {
199         return 0;
200     }
201
202     return 1;
203 }
204
205 static uint32_t fmt_ff2v4l(enum PixelFormat pix_fmt)
206 {
207     int i;
208
209     for (i = 0; i < sizeof(fmt_conversion_table) / sizeof(struct fmt_map); i++) {
210         if (fmt_conversion_table[i].ff_fmt == pix_fmt) {
211             return fmt_conversion_table[i].v4l2_fmt;
212         }
213     }
214
215     return 0;
216 }
217
218 static enum PixelFormat fmt_v4l2ff(uint32_t pix_fmt)
219 {
220     int i;
221
222     for (i = 0; i < sizeof(fmt_conversion_table) / sizeof(struct fmt_map); i++) {
223         if (fmt_conversion_table[i].v4l2_fmt == pix_fmt) {
224             return fmt_conversion_table[i].ff_fmt;
225         }
226     }
227
228     return PIX_FMT_NONE;
229 }
230
231 static int mmap_init(AVFormatContext *ctx)
232 {
233     struct video_data *s = ctx->priv_data;
234     struct v4l2_requestbuffers req;
235     int i, res;
236
237     memset(&req, 0, sizeof(struct v4l2_requestbuffers));
238     req.count = desired_video_buffers;
239     req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
240     req.memory = V4L2_MEMORY_MMAP;
241     res = ioctl (s->fd, VIDIOC_REQBUFS, &req);
242     if (res < 0) {
243         if (errno == EINVAL) {
244             av_log(ctx, AV_LOG_ERROR, "Device does not support mmap\n");
245         } else {
246             av_log(ctx, AV_LOG_ERROR, "ioctl(VIDIOC_REQBUFS)\n");
247         }
248
249         return -1;
250     }
251
252     if (req.count < 2) {
253         av_log(ctx, AV_LOG_ERROR, "Insufficient buffer memory\n");
254
255         return -1;
256     }
257     s->buffers = req.count;
258     s->buf_start = av_malloc(sizeof(void *) * s->buffers);
259     if (s->buf_start == NULL) {
260         av_log(ctx, AV_LOG_ERROR, "Cannot allocate buffer pointers\n");
261
262         return -1;
263     }
264     s->buf_len = av_malloc(sizeof(unsigned int) * s->buffers);
265     if (s->buf_len == NULL) {
266         av_log(ctx, AV_LOG_ERROR, "Cannot allocate buffer sizes\n");
267         av_free(s->buf_start);
268
269         return -1;
270     }
271
272     for (i = 0; i < req.count; i++) {
273         struct v4l2_buffer buf;
274
275         memset(&buf, 0, sizeof(struct v4l2_buffer));
276         buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
277         buf.memory = V4L2_MEMORY_MMAP;
278         buf.index = i;
279         res = ioctl (s->fd, VIDIOC_QUERYBUF, &buf);
280         if (res < 0) {
281             av_log(ctx, AV_LOG_ERROR, "ioctl(VIDIOC_QUERYBUF)\n");
282
283             return -1;
284         }
285
286         s->buf_len[i] = buf.length;
287         if (s->buf_len[i] < s->frame_size) {
288             av_log(ctx, AV_LOG_ERROR, "Buffer len [%d] = %d != %d\n", i, s->buf_len[i], s->frame_size);
289
290             return -1;
291         }
292         s->buf_start[i] = mmap (NULL, buf.length,
293                         PROT_READ | PROT_WRITE, MAP_SHARED, s->fd, buf.m.offset);
294         if (s->buf_start[i] == MAP_FAILED) {
295             av_log(ctx, AV_LOG_ERROR, "mmap: %s\n", strerror(errno));
296
297             return -1;
298         }
299     }
300
301     return 0;
302 }
303
304 static int read_init(AVFormatContext *ctx)
305 {
306     return -1;
307 }
308
309 static void mmap_release_buffer(AVPacket *pkt)
310 {
311     struct v4l2_buffer buf;
312     int res, fd;
313     struct buff_data *buf_descriptor = pkt->priv;
314
315     memset(&buf, 0, sizeof(struct v4l2_buffer));
316     buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
317     buf.memory = V4L2_MEMORY_MMAP;
318     buf.index = buf_descriptor->index;
319     fd = buf_descriptor->fd;
320     av_free(buf_descriptor);
321
322     res = ioctl (fd, VIDIOC_QBUF, &buf);
323     if (res < 0) {
324         av_log(NULL, AV_LOG_ERROR, "ioctl(VIDIOC_QBUF)\n");
325     }
326     pkt->data = NULL;
327     pkt->size = 0;
328 }
329
330 static int mmap_read_frame(AVFormatContext *ctx, AVPacket *pkt)
331 {
332     struct video_data *s = ctx->priv_data;
333     struct v4l2_buffer buf;
334     struct buff_data *buf_descriptor;
335     int res;
336
337     memset(&buf, 0, sizeof(struct v4l2_buffer));
338     buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
339     buf.memory = V4L2_MEMORY_MMAP;
340
341     /* FIXME: Some special treatment might be needed in case of loss of signal... */
342     while ((res = ioctl(s->fd, VIDIOC_DQBUF, &buf)) < 0 && (errno == EINTR));
343     if (res < 0) {
344         if (errno == EAGAIN) {
345             pkt->size = 0;
346
347             return AVERROR(EAGAIN);
348         }
349         av_log(ctx, AV_LOG_ERROR, "ioctl(VIDIOC_DQBUF): %s\n", strerror(errno));
350
351         return -1;
352     }
353     assert (buf.index < s->buffers);
354     if (buf.bytesused != s->frame_size) {
355         av_log(ctx, AV_LOG_ERROR, "The v4l2 frame is %d bytes, but %d bytes are expected\n", buf.bytesused, s->frame_size);
356
357         return -1;
358     }
359
360     /* Image is at s->buff_start[buf.index] */
361     pkt->data= s->buf_start[buf.index];
362     pkt->size = buf.bytesused;
363     pkt->pts = buf.timestamp.tv_sec * INT64_C(1000000) + buf.timestamp.tv_usec;
364     pkt->destruct = mmap_release_buffer;
365     buf_descriptor = av_malloc(sizeof(struct buff_data));
366     if (buf_descriptor == NULL) {
367         /* Something went wrong... Since av_malloc() failed, we cannot even
368          * allocate a buffer for memcopying into it
369          */
370         av_log(ctx, AV_LOG_ERROR, "Failed to allocate a buffer descriptor\n");
371         res = ioctl (s->fd, VIDIOC_QBUF, &buf);
372
373         return -1;
374     }
375     buf_descriptor->fd = s->fd;
376     buf_descriptor->index = buf.index;
377     pkt->priv = buf_descriptor;
378
379     return s->buf_len[buf.index];
380 }
381
382 static int read_frame(AVFormatContext *ctx, AVPacket *pkt)
383 {
384     return -1;
385 }
386
387 static int mmap_start(AVFormatContext *ctx)
388 {
389     struct video_data *s = ctx->priv_data;
390     enum v4l2_buf_type type;
391     int i, res;
392
393     for (i = 0; i < s->buffers; i++) {
394         struct v4l2_buffer buf;
395
396         memset(&buf, 0, sizeof(struct v4l2_buffer));
397         buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
398         buf.memory = V4L2_MEMORY_MMAP;
399         buf.index  = i;
400
401         res = ioctl (s->fd, VIDIOC_QBUF, &buf);
402         if (res < 0) {
403             av_log(ctx, AV_LOG_ERROR, "ioctl(VIDIOC_QBUF): %s\n", strerror(errno));
404
405             return -1;
406         }
407     }
408
409     type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
410     res = ioctl (s->fd, VIDIOC_STREAMON, &type);
411     if (res < 0) {
412         av_log(ctx, AV_LOG_ERROR, "ioctl(VIDIOC_STREAMON): %s\n", strerror(errno));
413
414         return -1;
415     }
416
417     return 0;
418 }
419
420 static void mmap_close(struct video_data *s)
421 {
422     enum v4l2_buf_type type;
423     int i;
424
425     type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
426     /* We do not check for the result, because we could
427      * not do anything about it anyway...
428      */
429     ioctl(s->fd, VIDIOC_STREAMOFF, &type);
430     for (i = 0; i < s->buffers; i++) {
431         munmap(s->buf_start[i], s->buf_len[i]);
432     }
433     av_free(s->buf_start);
434     av_free(s->buf_len);
435 }
436
437 static int v4l2_set_parameters( AVFormatContext *s1, AVFormatParameters *ap )
438 {
439     struct video_data *s = s1->priv_data;
440     struct v4l2_input input;
441     struct v4l2_standard standard;
442     int i;
443
444     if(ap->channel>=0) {
445         /* set tv video input */
446         memset (&input, 0, sizeof (input));
447         input.index = ap->channel;
448         if(ioctl (s->fd, VIDIOC_ENUMINPUT, &input) < 0) {
449             av_log(s1, AV_LOG_ERROR, "The V4L2 driver ioctl enum input failed:\n");
450             return AVERROR(EIO);
451         }
452
453         av_log(s1, AV_LOG_DEBUG, "The V4L2 driver set input_id: %d, input: %s\n",
454                ap->channel, input.name);
455         if(ioctl (s->fd, VIDIOC_S_INPUT, &input.index) < 0 ) {
456             av_log(s1, AV_LOG_ERROR, "The V4L2 driver ioctl set input(%d) failed\n",
457                    ap->channel);
458             return AVERROR(EIO);
459         }
460     }
461
462     if(ap->standard) {
463         av_log(s1, AV_LOG_DEBUG, "The V4L2 driver set standard: %s\n",
464                ap->standard );
465         /* set tv standard */
466         memset (&standard, 0, sizeof (standard));
467         for(i=0;;i++) {
468             standard.index = i;
469             if (ioctl(s->fd, VIDIOC_ENUMSTD, &standard) < 0) {
470                 av_log(s1, AV_LOG_ERROR, "The V4L2 driver ioctl set standard(%s) failed\n",
471                        ap->standard);
472                 return AVERROR(EIO);
473             }
474
475             if(!strcasecmp(standard.name, ap->standard)) {
476                 break;
477             }
478         }
479
480         av_log(s1, AV_LOG_DEBUG, "The V4L2 driver set standard: %s, id: %"PRIu64"\n",
481                ap->standard, standard.id);
482         if (ioctl(s->fd, VIDIOC_S_STD, &standard.id) < 0) {
483             av_log(s1, AV_LOG_ERROR, "The V4L2 driver ioctl set standard(%s) failed\n",
484                    ap->standard);
485             return AVERROR(EIO);
486         }
487     }
488
489     return 0;
490 }
491
492 static int v4l2_read_header(AVFormatContext *s1, AVFormatParameters *ap)
493 {
494     struct video_data *s = s1->priv_data;
495     AVStream *st;
496     int width, height;
497     int res, frame_rate, frame_rate_base;
498     uint32_t desired_format, capabilities;
499
500     if (ap->width <= 0 || ap->height <= 0) {
501         av_log(s1, AV_LOG_ERROR, "Wrong size (%dx%d)\n", ap->width, ap->height);
502         return -1;
503     }
504     if (ap->time_base.den <= 0) {
505         av_log(s1, AV_LOG_ERROR, "Wrong time base (%d)\n", ap->time_base.den);
506         return -1;
507     }
508
509     width = ap->width;
510     height = ap->height;
511     frame_rate = ap->time_base.den;
512     frame_rate_base = ap->time_base.num;
513
514     if((unsigned)width > 32767 || (unsigned)height > 32767) {
515         av_log(s1, AV_LOG_ERROR, "Wrong size (%dx%d)\n", width, height);
516
517         return -1;
518     }
519
520     st = av_new_stream(s1, 0);
521     if (!st) {
522         return AVERROR(ENOMEM);
523     }
524     av_set_pts_info(st, 64, 1, 1000000); /* 64 bits pts in us */
525
526     s->width = width;
527     s->height = height;
528     s->frame_rate      = frame_rate;
529     s->frame_rate_base = frame_rate_base;
530
531     capabilities = 0;
532     s->fd = device_open(s1, &capabilities);
533     if (s->fd < 0) {
534         return AVERROR(EIO);
535     }
536     av_log(s1, AV_LOG_INFO, "[%d]Capabilities: %x\n", s->fd, capabilities);
537
538     desired_format = fmt_ff2v4l(ap->pix_fmt);
539     if (desired_format == 0 || (device_init(s1, &width, &height, desired_format) < 0)) {
540         int i, done;
541
542         done = 0; i = 0;
543         while (!done) {
544             desired_format = fmt_conversion_table[i].v4l2_fmt;
545             if (device_init(s1, &width, &height, desired_format) < 0) {
546                 desired_format = 0;
547                 i++;
548             } else {
549                done = 1;
550             }
551             if (i == sizeof(fmt_conversion_table) / sizeof(struct fmt_map)) {
552                done = 1;
553             }
554         }
555     }
556     if (desired_format == 0) {
557         av_log(s1, AV_LOG_ERROR, "Cannot find a proper format.\n");
558         close(s->fd);
559
560         return AVERROR(EIO);
561     }
562     s->frame_format = desired_format;
563
564     if( v4l2_set_parameters( s1, ap ) < 0 )
565         return AVERROR(EIO);
566
567     st->codec->pix_fmt = fmt_v4l2ff(desired_format);
568     s->frame_size = avpicture_get_size(st->codec->pix_fmt, width, height);
569     if (capabilities & V4L2_CAP_STREAMING) {
570         s->io_method = io_mmap;
571         res = mmap_init(s1);
572         if (res == 0) {
573             res = mmap_start(s1);
574         }
575     } else {
576         s->io_method = io_read;
577         res = read_init(s1);
578     }
579     if (res < 0) {
580         close(s->fd);
581
582         return AVERROR(EIO);
583     }
584     s->top_field_first = first_field(s->fd);
585
586     st->codec->codec_type = CODEC_TYPE_VIDEO;
587     st->codec->codec_id = CODEC_ID_RAWVIDEO;
588     st->codec->width = width;
589     st->codec->height = height;
590     st->codec->time_base.den = frame_rate;
591     st->codec->time_base.num = frame_rate_base;
592     st->codec->bit_rate = s->frame_size * 1/av_q2d(st->codec->time_base) * 8;
593
594     return 0;
595 }
596
597 static int v4l2_read_packet(AVFormatContext *s1, AVPacket *pkt)
598 {
599     struct video_data *s = s1->priv_data;
600     int res;
601
602     if (s->io_method == io_mmap) {
603         av_init_packet(pkt);
604         res = mmap_read_frame(s1, pkt);
605     } else if (s->io_method == io_read) {
606         if (av_new_packet(pkt, s->frame_size) < 0)
607             return AVERROR(EIO);
608
609         res = read_frame(s1, pkt);
610     } else {
611         return AVERROR(EIO);
612     }
613     if (res < 0) {
614         return res;
615     }
616
617     if (s1->streams[0]->codec->coded_frame) {
618         s1->streams[0]->codec->coded_frame->interlaced_frame = 1;
619         s1->streams[0]->codec->coded_frame->top_field_first = s->top_field_first;
620     }
621
622     return s->frame_size;
623 }
624
625 static int v4l2_read_close(AVFormatContext *s1)
626 {
627     struct video_data *s = s1->priv_data;
628
629     if (s->io_method == io_mmap) {
630         mmap_close(s);
631     }
632
633     close(s->fd);
634     return 0;
635 }
636
637 AVInputFormat v4l2_demuxer = {
638     "video4linux2",
639     NULL_IF_CONFIG_SMALL("video grab"),
640     sizeof(struct video_data),
641     NULL,
642     v4l2_read_header,
643     v4l2_read_packet,
644     v4l2_read_close,
645     .flags = AVFMT_NOFILE,
646 };