v4l2.c 26 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>
Luca Barbato's avatar
Luca Barbato committed
39
#include <poll.h>
40
#if HAVE_SYS_VIDEOIO_H
41 42
#include <sys/videoio.h>
#else
43
#include <linux/videodev2.h>
44
#endif
Luca Abeni's avatar
Luca Abeni committed
45
#include <time.h>
46
#include "libavutil/imgutils.h"
47 48
#include "libavutil/log.h"
#include "libavutil/opt.h"
49
#include "libavutil/parseutils.h"
50
#include "libavutil/pixdesc.h"
51
#include "libavutil/avstring.h"
Luca Barbato's avatar
Luca Barbato committed
52
#include "libavutil/mathematics.h"
Luca Abeni's avatar
Luca Abeni committed
53 54 55

static const int desired_video_buffers = 256;

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

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

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

82 83 84 85 86
struct buff_data {
    int index;
    int fd;
};

Luca Abeni's avatar
Luca Abeni committed
87 88
struct fmt_map {
    enum PixelFormat ff_fmt;
89
    enum CodecID codec_id;
90
    uint32_t v4l2_fmt;
Luca Abeni's avatar
Luca Abeni committed
91 92 93
};

static struct fmt_map fmt_conversion_table[] = {
94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109
    //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
110 111
};

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

119 120 121
    if (ctx->flags & AVFMT_FLAG_NONBLOCK) {
        flags |= O_NONBLOCK;
    }
Luca Barbato's avatar
Luca Barbato committed
122

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

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

Luca Barbato's avatar
Luca Barbato committed
130
        return AVERROR(err);
Luca Abeni's avatar
Luca Abeni committed
131 132 133 134
    }

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

Luca Barbato's avatar
Luca Barbato committed
139
        goto fail;
Luca Abeni's avatar
Luca Abeni committed
140
    }
Luca Barbato's avatar
Luca Barbato committed
141

Luca Barbato's avatar
Luca Barbato committed
142 143 144 145 146 147
    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
148

Luca Barbato's avatar
Luca Barbato committed
149
        goto fail;
Luca Abeni's avatar
Luca Abeni committed
150
    }
Luca Barbato's avatar
Luca Barbato committed
151

Luca Barbato's avatar
Luca Barbato committed
152 153 154 155 156 157 158
    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
159 160

    return fd;
Luca Barbato's avatar
Luca Barbato committed
161 162 163 164

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

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

175
    int res;
Luca Abeni's avatar
Luca Abeni committed
176

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 334
{
    int i, res;
335 336 337 338 339 340
    struct video_data *s = ctx->priv_data;
    struct v4l2_requestbuffers req = {
        .type   = V4L2_BUF_TYPE_VIDEO_CAPTURE,
        .count  = desired_video_buffers,
        .memory = V4L2_MEMORY_MMAP
    };
Luca Abeni's avatar
Luca Abeni committed
341

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
    }

    for (i = 0; i < req.count; i++) {
374 375 376 377 378
        struct v4l2_buffer buf = {
            .type   = V4L2_BUF_TYPE_VIDEO_CAPTURE,
            .index  = i,
            .memory = V4L2_MEMORY_MMAP
        };
Luca Abeni's avatar
Luca Abeni committed
379

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
static void mmap_release_buffer(AVPacket *pkt)
{
411
    struct v4l2_buffer buf = { 0 };
412 413 414
    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
    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);

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

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

static int mmap_read_frame(AVFormatContext *ctx, AVPacket *pkt)
Luca Abeni's avatar
Luca Abeni committed
434
{
Luca Abeni's avatar
Luca Abeni committed
435
    struct video_data *s = ctx->priv_data;
436 437 438 439
    struct v4l2_buffer buf = {
        .type   = V4L2_BUF_TYPE_VIDEO_CAPTURE,
        .memory = V4L2_MEMORY_MMAP
    };
440
    struct buff_data *buf_descriptor;
Luca Barbato's avatar
Luca Barbato committed
441
    struct pollfd p = { .fd = s->fd, .events = POLLIN };
Luca Abeni's avatar
Luca Abeni committed
442 443
    int res;

Luca Barbato's avatar
Luca Barbato committed
444 445 446 447 448 449 450
    res = poll(&p, 1, s->timeout);
    if (res < 0)
        return AVERROR(errno);

    if (!(p.revents & (POLLIN | POLLERR | POLLHUP)))
        return AVERROR(EAGAIN);

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

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

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

470
        return AVERROR_INVALIDDATA;
471 472
    }

Luca Abeni's avatar
Luca Abeni committed
473
    /* Image is at s->buff_start[buf.index] */
474 475 476 477 478 479 480 481 482 483
    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");
484
        res = ioctl(s->fd, VIDIOC_QBUF, &buf);
Luca Abeni's avatar
Luca Abeni committed
485

486
        return AVERROR(ENOMEM);
Luca Abeni's avatar
Luca Abeni committed
487
    }
488 489 490
    buf_descriptor->fd = s->fd;
    buf_descriptor->index = buf.index;
    pkt->priv = buf_descriptor;
Luca Abeni's avatar
Luca Abeni committed
491 492 493 494

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

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

    for (i = 0; i < s->buffers; i++) {
502 503 504 505 506
        struct v4l2_buffer buf = {
            .type   = V4L2_BUF_TYPE_VIDEO_CAPTURE,
            .index  = i,
            .memory = V4L2_MEMORY_MMAP
        };
Luca Abeni's avatar
Luca Abeni committed
507

508
        res = ioctl(s->fd, VIDIOC_QBUF, &buf);
Luca Abeni's avatar
Luca Abeni committed
509
        if (res < 0) {
Luca Barbato's avatar
Luca Barbato committed
510 511
            av_log(ctx, AV_LOG_ERROR, "ioctl(VIDIOC_QBUF): %s\n",
                   strerror(errno));
Luca Abeni's avatar
Luca Abeni committed
512

513
            return AVERROR(errno);
Luca Abeni's avatar
Luca Abeni committed
514 515 516 517
        }
    }

    type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
518
    res = ioctl(s->fd, VIDIOC_STREAMON, &type);
Luca Abeni's avatar
Luca Abeni committed
519
    if (res < 0) {
Luca Barbato's avatar
Luca Barbato committed
520 521
        av_log(ctx, AV_LOG_ERROR, "ioctl(VIDIOC_STREAMON): %s\n",
               strerror(errno));
Luca Abeni's avatar
Luca Abeni committed
522

523
        return AVERROR(errno);
Luca Abeni's avatar
Luca Abeni committed
524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545
    }

    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);
}

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

556 557
    streamparm.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;

Luca Barbato's avatar
Luca Barbato committed
558 559 560 561
    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);
562 563
        return ret;
    }
564

Anton Khirnov's avatar
Anton Khirnov committed
565 566 567 568 569 570
    /* set tv video 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);
    }
571

Anton Khirnov's avatar
Anton Khirnov committed
572 573 574
    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
575 576
        av_log(s1, AV_LOG_ERROR,
               "The V4L2 driver ioctl set input(%d) failed\n",
Anton Khirnov's avatar
Anton Khirnov committed
577 578 579
                s->channel);
        return AVERROR(EIO);
    }
580

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

594
            if (!av_strcasecmp(standard.name, s->standard)) {
Luca Abeni's avatar
Luca Abeni committed
595 596 597 598
                break;
            }
        }

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

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

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

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

Luca Barbato's avatar
Luca Barbato committed
641 642 643 644
    s->timeout = 100 +
        av_rescale_q(1, s1->streams[0]->codec->time_base,
                        (AVRational){1, 1000});

645 646 647
    return 0;
}

648
static uint32_t device_try_init(AVFormatContext *s1,
649
                                enum PixelFormat pix_fmt,
650 651 652
                                int *width,
                                int *height,
                                enum CodecID *codec_id)
653
{
654
    uint32_t desired_format = fmt_ff2v4l(pix_fmt, s1->video_codec_id);
655 656 657 658 659 660 661

    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++) {
662 663
            if (s1->video_codec_id == CODEC_ID_NONE ||
                fmt_conversion_table[i].codec_id == s1->video_codec_id) {
664 665 666 667 668 669 670 671
                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
672

673 674 675 676 677 678 679 680
    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
681 682 683 684
static int v4l2_read_header(AVFormatContext *s1, AVFormatParameters *ap)
{
    struct video_data *s = s1->priv_data;
    AVStream *st;
685
    int res = 0;
Luca Barbato's avatar
Luca Barbato committed
686
    uint32_t desired_format;
687
    enum CodecID codec_id;
688
    enum PixelFormat pix_fmt = PIX_FMT_NONE;
Luca Abeni's avatar
Luca Abeni committed
689

690
    st = avformat_new_stream(s1, NULL);
Luca Abeni's avatar
Luca Abeni committed
691
    if (!st) {
692 693
        res = AVERROR(ENOMEM);
        goto out;
Luca Abeni's avatar
Luca Abeni committed
694
    }
Luca Barbato's avatar
Luca Barbato committed
695

Luca Barbato's avatar
Luca Barbato committed
696 697 698 699 700 701
    s->fd = device_open(s1);
    if (s->fd < 0) {
        res = s->fd;
        goto out;
    }

Luca Barbato's avatar
Luca Barbato committed
702 703 704 705 706 707
    if (s->list_format) {
        list_formats(s1, s->fd, s->list_format);
        res = AVERROR_EXIT;
        goto out;
    }

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

Luca Barbato's avatar
Luca Barbato committed
710 711 712 713
    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);
714 715
        goto out;
    }
Luca Barbato's avatar
Luca Barbato committed
716 717

    if (s->pixel_format) {
718 719 720 721
        AVCodec *codec = avcodec_find_decoder_by_name(s->pixel_format);

        if (codec)
            s1->video_codec_id = codec->id;
Luca Barbato's avatar
Luca Barbato committed
722 723 724

        pix_fmt = av_get_pix_fmt(s->pixel_format);

725 726
        if (pix_fmt == PIX_FMT_NONE && !codec) {
            av_log(s1, AV_LOG_ERROR, "No such input format: %s.\n",
Luca Barbato's avatar
Luca Barbato committed
727 728 729 730 731
                   s->pixel_format);

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

734 735 736
    if (!s->width && !s->height) {
        struct v4l2_format fmt;

Luca Barbato's avatar
Luca Barbato committed
737 738
        av_log(s1, AV_LOG_VERBOSE,
               "Querying the device for the current frame size\n");
739 740
        fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
        if (ioctl(s->fd, VIDIOC_G_FMT, &fmt) < 0) {
Luca Barbato's avatar
Luca Barbato committed
741 742
            av_log(s1, AV_LOG_ERROR, "ioctl(VIDIOC_G_FMT): %s\n",
                   strerror(errno));
743 744
            res = AVERROR(errno);
            goto out;
745
        }
Luca Barbato's avatar
Luca Barbato committed
746

747 748
        s->width  = fmt.fmt.pix.width;
        s->height = fmt.fmt.pix.height;
Luca Barbato's avatar
Luca Barbato committed
749 750
        av_log(s1, AV_LOG_VERBOSE,
               "Setting frame size to %dx%d\n", s->width, s->height);
751 752
    }

Luca Barbato's avatar
Luca Barbato committed
753 754
    desired_format = device_try_init(s1, pix_fmt, &s->width, &s->height,
                                     &codec_id);
Luca Abeni's avatar
Luca Abeni committed
755
    if (desired_format == 0) {
756
        av_log(s1, AV_LOG_ERROR, "Cannot find a proper format for "
757
               "codec_id %d, pix_fmt %d.\n", s1->video_codec_id, pix_fmt);
Luca Abeni's avatar
Luca Abeni committed
758 759
        close(s->fd);

760 761
        res = AVERROR(EIO);
        goto out;
Luca Abeni's avatar
Luca Abeni committed
762
    }
Luca Barbato's avatar
Luca Barbato committed
763

764 765
    if ((res = av_image_check_size(s->width, s->height, 0, s1) < 0))
        goto out;
Luca Barbato's avatar
Luca Barbato committed
766

Luca Abeni's avatar
Luca Abeni committed
767 768
    s->frame_format = desired_format;

769 770
    if ((res = v4l2_set_parameters(s1, ap) < 0))
        goto out;
771

772
    st->codec->pix_fmt = fmt_v4l2ff(desired_format, codec_id);
Luca Barbato's avatar
Luca Barbato committed
773 774 775
    s->frame_size =
        avpicture_get_size(st->codec->pix_fmt, s->width, s->height);

Luca Barbato's avatar
Luca Barbato committed
776 777
    if ((res = mmap_init(s1)) ||
        (res = mmap_start(s1)) < 0) {
Luca Abeni's avatar
Luca Abeni committed
778
        close(s->fd);
779
        goto out;
Luca Abeni's avatar
Luca Abeni committed
780
    }
Luca Barbato's avatar
Luca Barbato committed
781

Luca Abeni's avatar
Luca Abeni committed
782 783
    s->top_field_first = first_field(s->fd);

784
    st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
785
    st->codec->codec_id = codec_id;
Luca Barbato's avatar
Luca Barbato committed
786 787 788
    if (codec_id == CODEC_ID_RAWVIDEO)
        st->codec->codec_tag =
            avcodec_pix_fmt_to_codec_tag(st->codec->pix_fmt);
789 790
    st->codec->width = s->width;
    st->codec->height = s->height;
Luca Abeni's avatar
Luca Abeni committed
791 792
    st->codec->bit_rate = s->frame_size * 1/av_q2d(st->codec->time_base) * 8;

793 794
out:
    return res;
Luca Abeni's avatar
Luca Abeni committed
795 796 797 798 799
}

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

Luca Barbato's avatar
Luca Barbato committed
803 804
    av_init_packet(pkt);
    if ((res = mmap_read_frame(s1, pkt)) < 0) {
805
        return res;
Luca Abeni's avatar
Luca Abeni committed
806 807
    }

Luca Barbato's avatar
Luca Barbato committed
808 809 810
    if (frame && s->interlaced) {
        frame->interlaced_frame = 1;
        frame->top_field_first = s->top_field_first;
Luca Abeni's avatar
Luca Abeni committed
811 812
    }

813
    return pkt->size;
Luca Abeni's avatar
Luca Abeni committed
814 815 816 817 818 819
}

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

Luca Barbato's avatar
Luca Barbato committed
820
    mmap_close(s);
Luca Abeni's avatar
Luca Abeni committed
821 822 823 824 825

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

826 827
#define OFFSET(x) offsetof(struct video_data, x)
#define DEC AV_OPT_FLAG_DECODING_PARAM
828
static const AVOption options[] = {
829 830 831
    { "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 },
832 833
    { "pixel_format", "Preferred pixel format",                                    OFFSET(pixel_format), AV_OPT_TYPE_STRING, {.str = NULL},  0, 0,       DEC },
    { "input_format", "Preferred pixel format (for raw video) or codec name",      OFFSET(pixel_format), AV_OPT_TYPE_STRING, {.str = NULL},  0, 0,       DEC },
834
    { "framerate",    "",                                                          OFFSET(framerate),    AV_OPT_TYPE_STRING, {.str = NULL},  0, 0,       DEC },
Luca Barbato's avatar
Luca Barbato committed
835 836 837 838
    { "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" },
839 840 841 842 843 844 845 846 847 848
    { NULL },
};

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

849
AVInputFormat ff_v4l2_demuxer = {
850 851 852 853 854 855 856 857
    .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
858
};