v4l2.c 25.6 KB
Newer Older
Luca Abeni's avatar
Luca Abeni committed
1 2
/*
 * Video4Linux2 grab interface
3 4
 * Copyright (c) 2000,2001 Fabrice Bellard
 * Copyright (c) 2006 Luca Abeni
Luca Abeni's avatar
Luca Abeni committed
5 6 7 8 9 10 11 12
 *
 * Part of this file is based on the V4L2 video capture example
 * (http://v4l2spec.bytesex.org/v4l2spec/capture.c)
 *
 * Thanks to Michael Niedermayer for providing the mapping between
 * V4L2_PIX_FMT_* and PIX_FMT_*
 *
 *
13
 * This file is part of Libav.
14
 *
15
 * Libav is free software; you can redistribute it and/or
Luca Abeni's avatar
Luca Abeni committed
16 17
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
18
 * version 2.1 of the License, or (at your option) any later version.
Luca Abeni's avatar
Luca Abeni committed
19
 *
20
 * Libav is distributed in the hope that it will be useful,
Luca Abeni's avatar
Luca Abeni committed
21 22 23 24 25
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
26
 * License along with Libav; if not, write to the Free Software
Luca Abeni's avatar
Luca Abeni committed
27 28
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 */
29

30
#undef __STRICT_ANSI__ //workaround due to broken kernel headers
31
#include "config.h"
32
#include "libavformat/avformat.h"
33
#include "libavformat/internal.h"
Luca Abeni's avatar
Luca Abeni committed
34 35 36 37 38
#include <unistd.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <sys/time.h>
39
#if HAVE_SYS_VIDEOIO_H
40 41
#include <sys/videoio.h>
#else
42
#include <linux/videodev2.h>
43
#endif
Luca Abeni's avatar
Luca Abeni committed
44
#include <time.h>
45
#include "libavutil/imgutils.h"
46 47
#include "libavutil/log.h"
#include "libavutil/opt.h"
48
#include "libavutil/parseutils.h"
49
#include "libavutil/pixdesc.h"
50
#include "libavutil/avstring.h"
Luca Abeni's avatar
Luca Abeni committed
51 52 53

static const int desired_video_buffers = 256;

Luca Barbato's avatar
Luca Barbato committed
54 55 56 57
#define V4L_ALLFORMATS  3
#define V4L_RAWFORMATS  1
#define V4L_COMPFORMATS 2

Luca Abeni's avatar
Luca Abeni committed
58
struct video_data {
59
    AVClass *class;
Luca Abeni's avatar
Luca Abeni committed
60 61 62 63
    int fd;
    int frame_format; /* V4L2_PIX_FMT_* */
    int width, height;
    int frame_size;
64
    int interlaced;
Luca Abeni's avatar
Luca Abeni committed
65 66 67 68 69
    int top_field_first;

    int buffers;
    void **buf_start;
    unsigned int *buf_len;
70
    char *standard;
71
    int channel;
Luca Barbato's avatar
Luca Barbato committed
72 73
    char *video_size;   /**< String describing video size,
                             set by a private option. */
74
    char *pixel_format; /**< Set by a private option. */
Luca Barbato's avatar
Luca Barbato committed
75
    int list_format;    /**< Set by a private option. */
76
    char *framerate;    /**< Set by a private option. */
Luca Abeni's avatar
Luca Abeni committed
77 78
};

79 80 81 82 83
struct buff_data {
    int index;
    int fd;
};

Luca Abeni's avatar
Luca Abeni committed
84 85
struct fmt_map {
    enum PixelFormat ff_fmt;
86
    enum CodecID codec_id;
87
    uint32_t v4l2_fmt;
Luca Abeni's avatar
Luca Abeni committed
88 89 90
};

static struct fmt_map fmt_conversion_table[] = {
91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106
    //ff_fmt           codec_id           v4l2_fmt
    { PIX_FMT_YUV420P, CODEC_ID_RAWVIDEO, V4L2_PIX_FMT_YUV420  },
    { PIX_FMT_YUV422P, CODEC_ID_RAWVIDEO, V4L2_PIX_FMT_YUV422P },
    { PIX_FMT_YUYV422, CODEC_ID_RAWVIDEO, V4L2_PIX_FMT_YUYV    },
    { PIX_FMT_UYVY422, CODEC_ID_RAWVIDEO, V4L2_PIX_FMT_UYVY    },
    { PIX_FMT_YUV411P, CODEC_ID_RAWVIDEO, V4L2_PIX_FMT_YUV411P },
    { PIX_FMT_YUV410P, CODEC_ID_RAWVIDEO, V4L2_PIX_FMT_YUV410  },
    { PIX_FMT_RGB555,  CODEC_ID_RAWVIDEO, V4L2_PIX_FMT_RGB555  },
    { PIX_FMT_RGB565,  CODEC_ID_RAWVIDEO, V4L2_PIX_FMT_RGB565  },
    { PIX_FMT_BGR24,   CODEC_ID_RAWVIDEO, V4L2_PIX_FMT_BGR24   },
    { PIX_FMT_RGB24,   CODEC_ID_RAWVIDEO, V4L2_PIX_FMT_RGB24   },
    { PIX_FMT_BGRA,    CODEC_ID_RAWVIDEO, V4L2_PIX_FMT_BGR32   },
    { PIX_FMT_GRAY8,   CODEC_ID_RAWVIDEO, V4L2_PIX_FMT_GREY    },
    { PIX_FMT_NV12,    CODEC_ID_RAWVIDEO, V4L2_PIX_FMT_NV12    },
    { PIX_FMT_NONE,    CODEC_ID_MJPEG,    V4L2_PIX_FMT_MJPEG   },
    { PIX_FMT_NONE,    CODEC_ID_MJPEG,    V4L2_PIX_FMT_JPEG    },
Luca Abeni's avatar
Luca Abeni committed
107 108
};

Luca Barbato's avatar
Luca Barbato committed
109
static int device_open(AVFormatContext *ctx)
Luca Abeni's avatar
Luca Abeni committed
110 111 112
{
    struct v4l2_capability cap;
    int fd;
113
    int res, err;
114
    int flags = O_RDWR;
Luca Abeni's avatar
Luca Abeni committed
115

116 117 118
    if (ctx->flags & AVFMT_FLAG_NONBLOCK) {
        flags |= O_NONBLOCK;
    }
Luca Barbato's avatar
Luca Barbato committed
119

120
    fd = open(ctx->filename, flags, 0);
Luca Abeni's avatar
Luca Abeni committed
121
    if (fd < 0) {
Luca Barbato's avatar
Luca Barbato committed
122 123
        err = errno;

Luca Abeni's avatar
Luca Abeni committed
124
        av_log(ctx, AV_LOG_ERROR, "Cannot open video device %s : %s\n",
Luca Barbato's avatar
Luca Barbato committed
125
               ctx->filename, strerror(err));
Luca Abeni's avatar
Luca Abeni committed
126

Luca Barbato's avatar
Luca Barbato committed
127
        return AVERROR(err);
Luca Abeni's avatar
Luca Abeni committed
128 129 130 131
    }

    res = ioctl(fd, VIDIOC_QUERYCAP, &cap);
    if (res < 0) {
Luca Barbato's avatar
Luca Barbato committed
132
        err = errno;
Luca Abeni's avatar
Luca Abeni committed
133
        av_log(ctx, AV_LOG_ERROR, "ioctl(VIDIOC_QUERYCAP): %s\n",
Luca Barbato's avatar
Luca Barbato committed
134
               strerror(err));
Luca Abeni's avatar
Luca Abeni committed
135

Luca Barbato's avatar
Luca Barbato committed
136
        goto fail;
Luca Abeni's avatar
Luca Abeni committed
137
    }
Luca Barbato's avatar
Luca Barbato committed
138

Luca Barbato's avatar
Luca Barbato committed
139 140 141 142 143 144
    av_log(ctx, AV_LOG_VERBOSE, "[%d]Capabilities: %x\n",
           fd, cap.capabilities);

    if (!(cap.capabilities & V4L2_CAP_VIDEO_CAPTURE)) {
        av_log(ctx, AV_LOG_ERROR, "Not a video capture device.\n");
        err = ENODEV;
Luca Abeni's avatar
Luca Abeni committed
145

Luca Barbato's avatar
Luca Barbato committed
146
        goto fail;
Luca Abeni's avatar
Luca Abeni committed
147
    }
Luca Barbato's avatar
Luca Barbato committed
148

Luca Barbato's avatar
Luca Barbato committed
149 150 151 152 153 154 155
    if (!(cap.capabilities & V4L2_CAP_STREAMING)) {
        av_log(ctx, AV_LOG_ERROR,
               "The device does not support the streaming I/O method.\n");
        err = ENOSYS;

        goto fail;
    }
Luca Abeni's avatar
Luca Abeni committed
156 157

    return fd;
Luca Barbato's avatar
Luca Barbato committed
158 159 160 161

fail:
    close(fd);
    return AVERROR(err);
Luca Abeni's avatar
Luca Abeni committed
162 163
}

Luca Barbato's avatar
Luca Barbato committed
164 165
static int device_init(AVFormatContext *ctx, int *width, int *height,
                       uint32_t pix_fmt)
Luca Abeni's avatar
Luca Abeni committed
166
{
Luca Abeni's avatar
Luca Abeni committed
167 168
    struct video_data *s = ctx->priv_data;
    int fd = s->fd;
Luca Abeni's avatar
Luca Abeni committed
169
    struct v4l2_format fmt;
Luca Barbato's avatar
Luca Barbato committed
170 171
    struct v4l2_pix_format *pix = &fmt.fmt.pix;

172
    int res;
Luca Abeni's avatar
Luca Abeni committed
173 174

    memset(&fmt, 0, sizeof(struct v4l2_format));
Luca Barbato's avatar
Luca Barbato committed
175

Luca Abeni's avatar
Luca Abeni committed
176
    fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
Luca Barbato's avatar
Luca Barbato committed
177 178 179 180 181
    pix->width = *width;
    pix->height = *height;
    pix->pixelformat = pix_fmt;
    pix->field = V4L2_FIELD_ANY;

182
    res = ioctl(fd, VIDIOC_S_FMT, &fmt);
Luca Barbato's avatar
Luca Barbato committed
183

184
    if ((*width != fmt.fmt.pix.width) || (*height != fmt.fmt.pix.height)) {
Luca Barbato's avatar
Luca Barbato committed
185 186 187
        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);
188 189 190 191
        *width = fmt.fmt.pix.width;
        *height = fmt.fmt.pix.height;
    }

192
    if (pix_fmt != fmt.fmt.pix.pixelformat) {
Luca Barbato's avatar
Luca Barbato committed
193 194 195 196
        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);
197 198 199
        res = -1;
    }

200 201 202 203 204
    if (fmt.fmt.pix.field == V4L2_FIELD_INTERLACED) {
        av_log(ctx, AV_LOG_DEBUG, "The V4L2 driver using the interlaced mode");
        s->interlaced = 1;
    }

205
    return res;
Luca Abeni's avatar
Luca Abeni committed
206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223
}

static int first_field(int fd)
{
    int res;
    v4l2_std_id std;

    res = ioctl(fd, VIDIOC_G_STD, &std);
    if (res < 0) {
        return 0;
    }
    if (std & V4L2_STD_NTSC) {
        return 0;
    }

    return 1;
}

224
static uint32_t fmt_ff2v4l(enum PixelFormat pix_fmt, enum CodecID codec_id)
Luca Abeni's avatar
Luca Abeni committed
225 226 227
{
    int i;

228
    for (i = 0; i < FF_ARRAY_ELEMS(fmt_conversion_table); i++) {
229 230 231 232
        if ((codec_id == CODEC_ID_NONE ||
             fmt_conversion_table[i].codec_id == codec_id) &&
            (pix_fmt == PIX_FMT_NONE ||
             fmt_conversion_table[i].ff_fmt == pix_fmt)) {
Luca Abeni's avatar
Luca Abeni committed
233 234 235 236 237 238 239
            return fmt_conversion_table[i].v4l2_fmt;
        }
    }

    return 0;
}

240
static enum PixelFormat fmt_v4l2ff(uint32_t v4l2_fmt, enum CodecID codec_id)
Luca Abeni's avatar
Luca Abeni committed
241 242 243
{
    int i;

244
    for (i = 0; i < FF_ARRAY_ELEMS(fmt_conversion_table); i++) {
245 246
        if (fmt_conversion_table[i].v4l2_fmt == v4l2_fmt &&
            fmt_conversion_table[i].codec_id == codec_id) {
Luca Abeni's avatar
Luca Abeni committed
247 248 249 250
            return fmt_conversion_table[i].ff_fmt;
        }
    }

251
    return PIX_FMT_NONE;
Luca Abeni's avatar
Luca Abeni committed
252 253
}

254 255 256 257 258 259 260 261 262 263 264 265 266
static enum CodecID fmt_v4l2codec(uint32_t v4l2_fmt)
{
    int i;

    for (i = 0; i < FF_ARRAY_ELEMS(fmt_conversion_table); i++) {
        if (fmt_conversion_table[i].v4l2_fmt == v4l2_fmt) {
            return fmt_conversion_table[i].codec_id;
        }
    }

    return CODEC_ID_NONE;
}

Luca Barbato's avatar
Luca Barbato committed
267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318
#if HAVE_STRUCT_V4L2_FRMIVALENUM_DISCRETE
static void list_framesizes(AVFormatContext *ctx, int fd, uint32_t pixelformat)
{
    struct v4l2_frmsizeenum vfse = { .pixel_format = pixelformat };

    while(!ioctl(fd, VIDIOC_ENUM_FRAMESIZES, &vfse)) {
        switch (vfse.type) {
        case V4L2_FRMSIZE_TYPE_DISCRETE:
            av_log(ctx, AV_LOG_INFO, " %ux%u",
                   vfse.discrete.width, vfse.discrete.height);
        break;
        case V4L2_FRMSIZE_TYPE_CONTINUOUS:
        case V4L2_FRMSIZE_TYPE_STEPWISE:
            av_log(ctx, AV_LOG_INFO, " {%u-%u, %u}x{%u-%u, %u}",
                   vfse.stepwise.min_width,
                   vfse.stepwise.max_width,
                   vfse.stepwise.step_width,
                   vfse.stepwise.min_height,
                   vfse.stepwise.max_height,
                   vfse.stepwise.step_height);
        }
        vfse.index++;
    }
}
#endif

static void list_formats(AVFormatContext *ctx, int fd, int type)
{
    struct v4l2_fmtdesc vfd = { .type = V4L2_BUF_TYPE_VIDEO_CAPTURE };

    while(!ioctl(fd, VIDIOC_ENUM_FMT, &vfd)) {
        enum CodecID codec_id = fmt_v4l2codec(vfd.pixelformat);
        enum PixelFormat pix_fmt = fmt_v4l2ff(vfd.pixelformat, codec_id);

        vfd.index++;

        if (!(vfd.flags & V4L2_FMT_FLAG_COMPRESSED) &&
            type & V4L_RAWFORMATS) {
            const char *fmt_name = av_get_pix_fmt_name(pix_fmt);
            av_log(ctx, AV_LOG_INFO, "R : %9s : %20s :",
                   fmt_name ? fmt_name : "Unsupported",
                   vfd.description);
        } else if (vfd.flags & V4L2_FMT_FLAG_COMPRESSED &&
                   type & V4L_COMPFORMATS) {
            AVCodec *codec = avcodec_find_encoder(codec_id);
            av_log(ctx, AV_LOG_INFO, "C : %9s : %20s :",
                   codec ? codec->name : "Unsupported",
                   vfd.description);
        } else {
            continue;
        }

319
#ifdef V4L2_FMT_FLAG_EMULATED
Luca Barbato's avatar
Luca Barbato committed
320 321 322 323
        if (vfd.flags & V4L2_FMT_FLAG_EMULATED) {
            av_log(ctx, AV_LOG_WARNING, "%s", "Emulated");
            continue;
        }
324
#endif
Luca Barbato's avatar
Luca Barbato committed
325 326 327 328 329 330 331
#if HAVE_STRUCT_V4L2_FRMIVALENUM_DISCRETE
        list_framesizes(ctx, fd, vfd.pixelformat);
#endif
        av_log(ctx, AV_LOG_INFO, "\n");
    }
}

Luca Abeni's avatar
Luca Abeni committed
332
static int mmap_init(AVFormatContext *ctx)
Luca Abeni's avatar
Luca Abeni committed
333
{
Luca Abeni's avatar
Luca Abeni committed
334
    struct video_data *s = ctx->priv_data;
Luca Abeni's avatar
Luca Abeni committed
335 336 337 338 339 340 341
    struct v4l2_requestbuffers req;
    int i, res;

    memset(&req, 0, sizeof(struct v4l2_requestbuffers));
    req.count = desired_video_buffers;
    req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    req.memory = V4L2_MEMORY_MMAP;
342
    res = ioctl(s->fd, VIDIOC_REQBUFS, &req);
Luca Abeni's avatar
Luca Abeni committed
343 344
    if (res < 0) {
        if (errno == EINVAL) {
Luca Abeni's avatar
Luca Abeni committed
345
            av_log(ctx, AV_LOG_ERROR, "Device does not support mmap\n");
Luca Abeni's avatar
Luca Abeni committed
346
        } else {
Luca Abeni's avatar
Luca Abeni committed
347
            av_log(ctx, AV_LOG_ERROR, "ioctl(VIDIOC_REQBUFS)\n");
Luca Abeni's avatar
Luca Abeni committed
348 349
        }

350
        return AVERROR(errno);
Luca Abeni's avatar
Luca Abeni committed
351 352 353
    }

    if (req.count < 2) {
Luca Abeni's avatar
Luca Abeni committed
354
        av_log(ctx, AV_LOG_ERROR, "Insufficient buffer memory\n");
Luca Abeni's avatar
Luca Abeni committed
355

356
        return AVERROR(ENOMEM);
Luca Abeni's avatar
Luca Abeni committed
357 358 359 360
    }
    s->buffers = req.count;
    s->buf_start = av_malloc(sizeof(void *) * s->buffers);
    if (s->buf_start == NULL) {
Luca Abeni's avatar
Luca Abeni committed
361
        av_log(ctx, AV_LOG_ERROR, "Cannot allocate buffer pointers\n");
Luca Abeni's avatar
Luca Abeni committed
362

363
        return AVERROR(ENOMEM);
Luca Abeni's avatar
Luca Abeni committed
364 365 366
    }
    s->buf_len = av_malloc(sizeof(unsigned int) * s->buffers);
    if (s->buf_len == NULL) {
Luca Abeni's avatar
Luca Abeni committed
367
        av_log(ctx, AV_LOG_ERROR, "Cannot allocate buffer sizes\n");
Luca Abeni's avatar
Luca Abeni committed
368 369
        av_free(s->buf_start);

370
        return AVERROR(ENOMEM);
Luca Abeni's avatar
Luca Abeni committed
371 372 373 374 375 376 377 378 379
    }

    for (i = 0; i < req.count; i++) {
        struct v4l2_buffer buf;

        memset(&buf, 0, sizeof(struct v4l2_buffer));
        buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
        buf.memory = V4L2_MEMORY_MMAP;
        buf.index = i;
380
        res = ioctl(s->fd, VIDIOC_QUERYBUF, &buf);
Luca Abeni's avatar
Luca Abeni committed
381
        if (res < 0) {
Luca Abeni's avatar
Luca Abeni committed
382
            av_log(ctx, AV_LOG_ERROR, "ioctl(VIDIOC_QUERYBUF)\n");
Luca Abeni's avatar
Luca Abeni committed
383

384
            return AVERROR(errno);
Luca Abeni's avatar
Luca Abeni committed
385 386 387
        }

        s->buf_len[i] = buf.length;
388
        if (s->frame_size > 0 && s->buf_len[i] < s->frame_size) {
Luca Barbato's avatar
Luca Barbato committed
389 390 391
            av_log(ctx, AV_LOG_ERROR,
                   "Buffer len [%d] = %d != %d\n",
                   i, s->buf_len[i], s->frame_size);
Luca Abeni's avatar
Luca Abeni committed
392 393 394

            return -1;
        }
Luca Barbato's avatar
Luca Barbato committed
395 396 397 398
        s->buf_start[i] = mmap(NULL, buf.length,
                               PROT_READ | PROT_WRITE, MAP_SHARED,
                               s->fd, buf.m.offset);

Luca Abeni's avatar
Luca Abeni committed
399
        if (s->buf_start[i] == MAP_FAILED) {
Luca Abeni's avatar
Luca Abeni committed
400
            av_log(ctx, AV_LOG_ERROR, "mmap: %s\n", strerror(errno));
Luca Abeni's avatar
Luca Abeni committed
401

402
            return AVERROR(errno);
Luca Abeni's avatar
Luca Abeni committed
403 404 405 406 407 408
        }
    }

    return 0;
}

409 410 411 412 413 414
static void mmap_release_buffer(AVPacket *pkt)
{
    struct v4l2_buffer buf;
    int res, fd;
    struct buff_data *buf_descriptor = pkt->priv;

Luca Barbato's avatar
Luca Barbato committed
415 416
    if (pkt->data == NULL)
        return;
417

418 419 420 421 422 423 424
    memset(&buf, 0, sizeof(struct v4l2_buffer));
    buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    buf.memory = V4L2_MEMORY_MMAP;
    buf.index = buf_descriptor->index;
    fd = buf_descriptor->fd;
    av_free(buf_descriptor);

425
    res = ioctl(fd, VIDIOC_QBUF, &buf);
Luca Barbato's avatar
Luca Barbato committed
426 427 428 429
    if (res < 0)
        av_log(NULL, AV_LOG_ERROR, "ioctl(VIDIOC_QBUF): %s\n",
               strerror(errno));

430 431 432 433 434
    pkt->data = NULL;
    pkt->size = 0;
}

static int mmap_read_frame(AVFormatContext *ctx, AVPacket *pkt)
Luca Abeni's avatar
Luca Abeni committed
435
{
Luca Abeni's avatar
Luca Abeni committed
436
    struct video_data *s = ctx->priv_data;
Luca Abeni's avatar
Luca Abeni committed
437
    struct v4l2_buffer buf;
438
    struct buff_data *buf_descriptor;
Luca Abeni's avatar
Luca Abeni committed
439 440 441 442 443 444 445
    int res;

    memset(&buf, 0, sizeof(struct v4l2_buffer));
    buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    buf.memory = V4L2_MEMORY_MMAP;

    /* FIXME: Some special treatment might be needed in case of loss of signal... */
446
    while ((res = ioctl(s->fd, VIDIOC_DQBUF, &buf)) < 0 && (errno == EINTR));
Luca Abeni's avatar
Luca Abeni committed
447
    if (res < 0) {
448 449 450 451 452
        if (errno == EAGAIN) {
            pkt->size = 0;

            return AVERROR(EAGAIN);
        }
Luca Barbato's avatar
Luca Barbato committed
453 454
        av_log(ctx, AV_LOG_ERROR, "ioctl(VIDIOC_DQBUF): %s\n",
               strerror(errno));
Luca Abeni's avatar
Luca Abeni committed
455

456
        return AVERROR(errno);
Luca Abeni's avatar
Luca Abeni committed
457 458
    }
    assert (buf.index < s->buffers);
459
    if (s->frame_size > 0 && buf.bytesused != s->frame_size) {
Luca Barbato's avatar
Luca Barbato committed
460 461 462
        av_log(ctx, AV_LOG_ERROR,
               "The v4l2 frame is %d bytes, but %d bytes are expected\n",
               buf.bytesused, s->frame_size);
463

464
        return AVERROR_INVALIDDATA;
465 466
    }

Luca Abeni's avatar
Luca Abeni committed
467
    /* Image is at s->buff_start[buf.index] */
468 469 470 471 472 473 474 475 476 477
    pkt->data= s->buf_start[buf.index];
    pkt->size = buf.bytesused;
    pkt->pts = buf.timestamp.tv_sec * INT64_C(1000000) + buf.timestamp.tv_usec;
    pkt->destruct = mmap_release_buffer;
    buf_descriptor = av_malloc(sizeof(struct buff_data));
    if (buf_descriptor == NULL) {
        /* Something went wrong... Since av_malloc() failed, we cannot even
         * allocate a buffer for memcopying into it
         */
        av_log(ctx, AV_LOG_ERROR, "Failed to allocate a buffer descriptor\n");
478
        res = ioctl(s->fd, VIDIOC_QBUF, &buf);
Luca Abeni's avatar
Luca Abeni committed
479

480
        return AVERROR(ENOMEM);
Luca Abeni's avatar
Luca Abeni committed
481
    }
482 483 484
    buf_descriptor->fd = s->fd;
    buf_descriptor->index = buf.index;
    pkt->priv = buf_descriptor;
Luca Abeni's avatar
Luca Abeni committed
485 486 487 488

    return s->buf_len[buf.index];
}

Luca Abeni's avatar
Luca Abeni committed
489
static int mmap_start(AVFormatContext *ctx)
Luca Abeni's avatar
Luca Abeni committed
490
{
Luca Abeni's avatar
Luca Abeni committed
491
    struct video_data *s = ctx->priv_data;
Luca Abeni's avatar
Luca Abeni committed
492 493 494 495 496 497 498 499 500 501 502
    enum v4l2_buf_type type;
    int i, res;

    for (i = 0; i < s->buffers; i++) {
        struct v4l2_buffer buf;

        memset(&buf, 0, sizeof(struct v4l2_buffer));
        buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
        buf.memory = V4L2_MEMORY_MMAP;
        buf.index  = i;

503
        res = ioctl(s->fd, VIDIOC_QBUF, &buf);
Luca Abeni's avatar
Luca Abeni committed
504
        if (res < 0) {
Luca Barbato's avatar
Luca Barbato committed
505 506
            av_log(ctx, AV_LOG_ERROR, "ioctl(VIDIOC_QBUF): %s\n",
                   strerror(errno));
Luca Abeni's avatar
Luca Abeni committed
507

508
            return AVERROR(errno);
Luca Abeni's avatar
Luca Abeni committed
509 510 511 512
        }
    }

    type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
513
    res = ioctl(s->fd, VIDIOC_STREAMON, &type);
Luca Abeni's avatar
Luca Abeni committed
514
    if (res < 0) {
Luca Barbato's avatar
Luca Barbato committed
515 516
        av_log(ctx, AV_LOG_ERROR, "ioctl(VIDIOC_STREAMON): %s\n",
               strerror(errno));
Luca Abeni's avatar
Luca Abeni committed
517

518
        return AVERROR(errno);
Luca Abeni's avatar
Luca Abeni committed
519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540
    }

    return 0;
}

static void mmap_close(struct video_data *s)
{
    enum v4l2_buf_type type;
    int i;

    type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    /* We do not check for the result, because we could
     * not do anything about it anyway...
     */
    ioctl(s->fd, VIDIOC_STREAMOFF, &type);
    for (i = 0; i < s->buffers; i++) {
        munmap(s->buf_start[i], s->buf_len[i]);
    }
    av_free(s->buf_start);
    av_free(s->buf_len);
}

541
static int v4l2_set_parameters(AVFormatContext *s1, AVFormatParameters *ap)
542 543 544 545
{
    struct video_data *s = s1->priv_data;
    struct v4l2_input input;
    struct v4l2_standard standard;
546 547
    struct v4l2_streamparm streamparm = { 0 };
    struct v4l2_fract *tpf = &streamparm.parm.capture.timeperframe;
548
    int i, ret;
549
    AVRational framerate_q;
550

551 552
    streamparm.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;

Luca Barbato's avatar
Luca Barbato committed
553 554 555 556
    if (s->framerate &&
        (ret = av_parse_video_rate(&framerate_q, s->framerate)) < 0) {
        av_log(s1, AV_LOG_ERROR, "Could not parse framerate '%s'.\n",
               s->framerate);
557 558
        return ret;
    }
559

Anton Khirnov's avatar
Anton Khirnov committed
560 561 562 563 564 565 566
    /* set tv video input */
    memset (&input, 0, sizeof (input));
    input.index = s->channel;
    if (ioctl(s->fd, VIDIOC_ENUMINPUT, &input) < 0) {
        av_log(s1, AV_LOG_ERROR, "The V4L2 driver ioctl enum input failed:\n");
        return AVERROR(EIO);
    }
567

Anton Khirnov's avatar
Anton Khirnov committed
568 569 570
    av_log(s1, AV_LOG_DEBUG, "The V4L2 driver set input_id: %d, input: %s\n",
            s->channel, input.name);
    if (ioctl(s->fd, VIDIOC_S_INPUT, &input.index) < 0) {
Luca Barbato's avatar
Luca Barbato committed
571 572
        av_log(s1, AV_LOG_ERROR,
               "The V4L2 driver ioctl set input(%d) failed\n",
Anton Khirnov's avatar
Anton Khirnov committed
573 574 575
                s->channel);
        return AVERROR(EIO);
    }
576

577
    if (s->standard) {
Luca Abeni's avatar
Luca Abeni committed
578
        av_log(s1, AV_LOG_DEBUG, "The V4L2 driver set standard: %s\n",
579
               s->standard);
Luca Abeni's avatar
Luca Abeni committed
580 581 582 583 584
        /* set tv standard */
        memset (&standard, 0, sizeof (standard));
        for(i=0;;i++) {
            standard.index = i;
            if (ioctl(s->fd, VIDIOC_ENUMSTD, &standard) < 0) {
Luca Barbato's avatar
Luca Barbato committed
585 586
                av_log(s1, AV_LOG_ERROR,
                       "The V4L2 driver ioctl set standard(%s) failed\n",
587
                       s->standard);
588
                return AVERROR(EIO);
Luca Abeni's avatar
Luca Abeni committed
589 590
            }

591
            if (!av_strcasecmp(standard.name, s->standard)) {
Luca Abeni's avatar
Luca Abeni committed
592 593 594 595
                break;
            }
        }

Luca Barbato's avatar
Luca Barbato committed
596 597
        av_log(s1, AV_LOG_DEBUG,
               "The V4L2 driver set standard: %s, id: %"PRIu64"\n",
598
               s->standard, (uint64_t)standard.id);
Luca Abeni's avatar
Luca Abeni committed
599
        if (ioctl(s->fd, VIDIOC_S_STD, &standard.id) < 0) {
Luca Barbato's avatar
Luca Barbato committed
600 601
            av_log(s1, AV_LOG_ERROR,
                   "The V4L2 driver ioctl set standard(%s) failed\n",
602
                   s->standard);
603
            return AVERROR(EIO);
604
        }
605
    }
606

607
    if (framerate_q.num && framerate_q.den) {
608
        av_log(s1, AV_LOG_DEBUG, "Setting time per frame to %d/%d\n",
609 610 611
               framerate_q.den, framerate_q.num);
        tpf->numerator   = framerate_q.den;
        tpf->denominator = framerate_q.num;
Luca Barbato's avatar
Luca Barbato committed
612

613 614 615
        if (ioctl(s->fd, VIDIOC_S_PARM, &streamparm) != 0) {
            av_log(s1, AV_LOG_ERROR,
                   "ioctl set time per frame(%d/%d) failed\n",
616
                   framerate_q.den, framerate_q.num);
617 618 619
            return AVERROR(EIO);
        }

620 621
        if (framerate_q.num != tpf->denominator ||
            framerate_q.den != tpf->numerator) {
622
            av_log(s1, AV_LOG_INFO,
Luca Barbato's avatar
Luca Barbato committed
623 624
                   "The driver changed the time per frame from "
                   "%d/%d to %d/%d\n",
625
                   framerate_q.den, framerate_q.num,
626 627
                   tpf->numerator, tpf->denominator);
        }
628 629
    } else {
        if (ioctl(s->fd, VIDIOC_G_PARM, &streamparm) != 0) {
Luca Barbato's avatar
Luca Barbato committed
630 631
            av_log(s1, AV_LOG_ERROR, "ioctl(VIDIOC_G_PARM): %s\n",
                   strerror(errno));
632 633
            return AVERROR(errno);
        }
634
    }
635 636
    s1->streams[0]->codec->time_base.den = tpf->denominator;
    s1->streams[0]->codec->time_base.num = tpf->numerator;
637

638 639 640
    return 0;
}

641
static uint32_t device_try_init(AVFormatContext *s1,
642
                                enum PixelFormat pix_fmt,
643 644 645
                                int *width,
                                int *height,
                                enum CodecID *codec_id)
646
{
647
    uint32_t desired_format = fmt_ff2v4l(pix_fmt, s1->video_codec_id);
648 649 650 651 652 653 654

    if (desired_format == 0 ||
        device_init(s1, width, height, desired_format) < 0) {
        int i;

        desired_format = 0;
        for (i = 0; i<FF_ARRAY_ELEMS(fmt_conversion_table); i++) {
655 656
            if (s1->video_codec_id == CODEC_ID_NONE ||
                fmt_conversion_table[i].codec_id == s1->video_codec_id) {
657 658 659 660 661 662 663 664
                desired_format = fmt_conversion_table[i].v4l2_fmt;
                if (device_init(s1, width, height, desired_format) >= 0) {
                    break;
                }
                desired_format = 0;
            }
        }
    }
Luca Barbato's avatar
Luca Barbato committed
665

666 667 668 669 670 671 672 673
    if (desired_format != 0) {
        *codec_id = fmt_v4l2codec(desired_format);
        assert(*codec_id != CODEC_ID_NONE);
    }

    return desired_format;
}

Luca Abeni's avatar
Luca Abeni committed
674 675 676 677
static int v4l2_read_header(AVFormatContext *s1, AVFormatParameters *ap)
{
    struct video_data *s = s1->priv_data;
    AVStream *st;
678
    int res = 0;
Luca Barbato's avatar
Luca Barbato committed
679
    uint32_t desired_format;
680
    enum CodecID codec_id;
681
    enum PixelFormat pix_fmt = PIX_FMT_NONE;
Luca Abeni's avatar
Luca Abeni committed
682

683
    st = avformat_new_stream(s1, NULL);
Luca Abeni's avatar
Luca Abeni committed
684
    if (!st) {
685 686
        res = AVERROR(ENOMEM);
        goto out;
Luca Abeni's avatar
Luca Abeni committed
687
    }
Luca Barbato's avatar
Luca Barbato committed
688

Luca Barbato's avatar
Luca Barbato committed
689 690 691 692 693 694
    s->fd = device_open(s1);
    if (s->fd < 0) {
        res = s->fd;
        goto out;
    }

Luca Barbato's avatar
Luca Barbato committed
695 696 697 698 699 700
    if (s->list_format) {
        list_formats(s1, s->fd, s->list_format);
        res = AVERROR_EXIT;
        goto out;
    }

701
    avpriv_set_pts_info(st, 64, 1, 1000000); /* 64 bits pts in us */
Luca Abeni's avatar
Luca Abeni committed
702

Luca Barbato's avatar
Luca Barbato committed
703 704 705 706
    if (s->video_size &&
        (res = av_parse_video_size(&s->width, &s->height, s->video_size)) < 0) {
        av_log(s1, AV_LOG_ERROR, "Could not parse video size '%s'.\n",
               s->video_size);
707 708
        goto out;
    }
Luca Barbato's avatar
Luca Barbato committed
709 710 711 712 713 714 715 716 717 718 719 720

    if (s->pixel_format) {

        pix_fmt = av_get_pix_fmt(s->pixel_format);

        if (pix_fmt == PIX_FMT_NONE) {
            av_log(s1, AV_LOG_ERROR, "No such pixel format: %s.\n",
                   s->pixel_format);

            res = AVERROR(EINVAL);
            goto out;
        }
721
    }
Luca Abeni's avatar
Luca Abeni committed
722

723 724 725
    if (!s->width && !s->height) {
        struct v4l2_format fmt;

Luca Barbato's avatar
Luca Barbato committed
726 727
        av_log(s1, AV_LOG_VERBOSE,
               "Querying the device for the current frame size\n");
728 729
        fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
        if (ioctl(s->fd, VIDIOC_G_FMT, &fmt) < 0) {
Luca Barbato's avatar
Luca Barbato committed
730 731
            av_log(s1, AV_LOG_ERROR, "ioctl(VIDIOC_G_FMT): %s\n",
                   strerror(errno));
732 733
            res = AVERROR(errno);
            goto out;
734
        }
Luca Barbato's avatar
Luca Barbato committed
735

736 737
        s->width  = fmt.fmt.pix.width;
        s->height = fmt.fmt.pix.height;
Luca Barbato's avatar
Luca Barbato committed
738 739
        av_log(s1, AV_LOG_VERBOSE,
               "Setting frame size to %dx%d\n", s->width, s->height);
740 741
    }

Luca Barbato's avatar
Luca Barbato committed
742 743
    desired_format = device_try_init(s1, pix_fmt, &s->width, &s->height,
                                     &codec_id);
Luca Abeni's avatar
Luca Abeni committed
744
    if (desired_format == 0) {
745
        av_log(s1, AV_LOG_ERROR, "Cannot find a proper format for "
746
               "codec_id %d, pix_fmt %d.\n", s1->video_codec_id, pix_fmt);
Luca Abeni's avatar
Luca Abeni committed
747 748
        close(s->fd);

749 750
        res = AVERROR(EIO);
        goto out;
Luca Abeni's avatar
Luca Abeni committed
751
    }
Luca Barbato's avatar
Luca Barbato committed
752

753 754
    if ((res = av_image_check_size(s->width, s->height, 0, s1) < 0))
        goto out;
Luca Barbato's avatar
Luca Barbato committed
755

Luca Abeni's avatar
Luca Abeni committed
756 757
    s->frame_format = desired_format;

758 759
    if ((res = v4l2_set_parameters(s1, ap) < 0))
        goto out;
760

761
    st->codec->pix_fmt = fmt_v4l2ff(desired_format, codec_id);
Luca Barbato's avatar
Luca Barbato committed
762 763 764
    s->frame_size =
        avpicture_get_size(st->codec->pix_fmt, s->width, s->height);

Luca Barbato's avatar
Luca Barbato committed
765 766
    if ((res = mmap_init(s1)) ||
        (res = mmap_start(s1)) < 0) {
Luca Abeni's avatar
Luca Abeni committed
767
        close(s->fd);
768
        goto out;
Luca Abeni's avatar
Luca Abeni committed
769
    }
Luca Barbato's avatar
Luca Barbato committed
770

Luca Abeni's avatar
Luca Abeni committed
771 772
    s->top_field_first = first_field(s->fd);

773
    st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
774
    st->codec->codec_id = codec_id;
Luca Barbato's avatar
Luca Barbato committed
775 776 777
    if (codec_id == CODEC_ID_RAWVIDEO)
        st->codec->codec_tag =
            avcodec_pix_fmt_to_codec_tag(st->codec->pix_fmt);
778 779
    st->codec->width = s->width;
    st->codec->height = s->height;
Luca Abeni's avatar
Luca Abeni committed
780 781
    st->codec->bit_rate = s->frame_size * 1/av_q2d(st->codec->time_base) * 8;

782 783
out:
    return res;
Luca Abeni's avatar
Luca Abeni committed
784 785 786 787 788
}

static int v4l2_read_packet(AVFormatContext *s1, AVPacket *pkt)
{
    struct video_data *s = s1->priv_data;
Luca Barbato's avatar
Luca Barbato committed
789
    AVFrame *frame = s1->streams[0]->codec->coded_frame;
Luca Abeni's avatar
Luca Abeni committed
790 791
    int res;

Luca Barbato's avatar
Luca Barbato committed
792 793
    av_init_packet(pkt);
    if ((res = mmap_read_frame(s1, pkt)) < 0) {
794
        return res;
Luca Abeni's avatar
Luca Abeni committed
795 796
    }

Luca Barbato's avatar
Luca Barbato committed
797 798 799
    if (frame && s->interlaced) {
        frame->interlaced_frame = 1;
        frame->top_field_first = s->top_field_first;
Luca Abeni's avatar
Luca Abeni committed
800 801
    }

802
    return pkt->size;
Luca Abeni's avatar
Luca Abeni committed
803 804 805 806 807 808
}

static int v4l2_read_close(AVFormatContext *s1)
{
    struct video_data *s = s1->priv_data;

Luca Barbato's avatar
Luca Barbato committed
809
    mmap_close(s);
Luca Abeni's avatar
Luca Abeni committed
810 811 812 813 814

    close(s->fd);
    return 0;
}

815 816
#define OFFSET(x) offsetof(struct video_data, x)
#define DEC AV_OPT_FLAG_DECODING_PARAM
817
static const AVOption options[] = {
818 819 820 821 822
    { "standard",     "TV standard, used only by analog frame grabber",            OFFSET(standard),     AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0,       DEC },
    { "channel",      "TV channel, used only by frame grabber",                    OFFSET(channel),      AV_OPT_TYPE_INT,    {.dbl = 0 },    0, INT_MAX, DEC },
    { "video_size",   "A string describing frame size, such as 640x480 or hd720.", OFFSET(video_size),   AV_OPT_TYPE_STRING, {.str = NULL},  0, 0,       DEC },
    { "pixel_format", "",                                                          OFFSET(pixel_format), AV_OPT_TYPE_STRING, {.str = NULL},  0, 0,       DEC },
    { "framerate",    "",                                                          OFFSET(framerate),    AV_OPT_TYPE_STRING, {.str = NULL},  0, 0,       DEC },
Luca Barbato's avatar
Luca Barbato committed
823 824 825 826
    { "list_formats", "List available formats and exit",                           OFFSET(list_format),  AV_OPT_TYPE_INT,    {.dbl = 0 },  0, INT_MAX, DEC, "list_formats" },
    { "all",          "Show all available formats",                                OFFSET(list_format),  AV_OPT_TYPE_CONST,  {.dbl = V4L_ALLFORMATS  },    0, INT_MAX, DEC, "list_formats" },
    { "raw",          "Show only non-compressed formats",                          OFFSET(list_format),  AV_OPT_TYPE_CONST,  {.dbl = V4L_RAWFORMATS  },    0, INT_MAX, DEC, "list_formats" },
    { "compressed",   "Show only compressed formats",                              OFFSET(list_format),  AV_OPT_TYPE_CONST,  {.dbl = V4L_COMPFORMATS },    0, INT_MAX, DEC, "list_formats" },
827 828 829 830 831 832 833 834 835 836
    { NULL },
};

static const AVClass v4l2_class = {
    .class_name = "V4L2 indev",
    .item_name  = av_default_item_name,
    .option     = options,
    .version    = LIBAVUTIL_VERSION_INT,
};

837
AVInputFormat ff_v4l2_demuxer = {
838 839 840 841 842 843 844 845
    .name           = "video4linux2",
    .long_name      = NULL_IF_CONFIG_SMALL("Video4Linux2 device grab"),
    .priv_data_size = sizeof(struct video_data),
    .read_header    = v4l2_read_header,
    .read_packet    = v4l2_read_packet,
    .read_close     = v4l2_read_close,
    .flags          = AVFMT_NOFILE,
    .priv_class     = &v4l2_class,
Luca Abeni's avatar
Luca Abeni committed
846
};