v4l2.c 26.3 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;
Luca Abeni's avatar
Luca Abeni committed
172
    struct v4l2_format fmt;
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 177

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

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

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

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

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

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

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

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

227
static uint32_t fmt_ff2v4l(enum PixelFormat pix_fmt, enum CodecID codec_id)
Luca Abeni's avatar
Luca Abeni committed
228 229 230
{
    int i;

231
    for (i = 0; i < FF_ARRAY_ELEMS(fmt_conversion_table); i++) {
232 233 234 235
        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
236 237 238 239 240 241 242
            return fmt_conversion_table[i].v4l2_fmt;
        }
    }

    return 0;
}

243
static enum PixelFormat fmt_v4l2ff(uint32_t v4l2_fmt, enum CodecID codec_id)
Luca Abeni's avatar
Luca Abeni committed
244 245 246
{
    int i;

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

254
    return PIX_FMT_NONE;
Luca Abeni's avatar
Luca Abeni committed
255 256
}

257 258 259 260 261 262 263 264 265 266 267 268 269
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
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 319 320 321
#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;
        }

322
#ifdef V4L2_FMT_FLAG_EMULATED
Luca Barbato's avatar
Luca Barbato committed
323 324 325 326
        if (vfd.flags & V4L2_FMT_FLAG_EMULATED) {
            av_log(ctx, AV_LOG_WARNING, "%s", "Emulated");
            continue;
        }
327
#endif
Luca Barbato's avatar
Luca Barbato committed
328 329 330 331 332 333 334
#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
335
static int mmap_init(AVFormatContext *ctx)
Luca Abeni's avatar
Luca Abeni committed
336
{
Luca Abeni's avatar
Luca Abeni committed
337
    struct video_data *s = ctx->priv_data;
Luca Abeni's avatar
Luca Abeni committed
338 339 340 341 342 343 344
    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;
345
    res = ioctl(s->fd, VIDIOC_REQBUFS, &req);
Luca Abeni's avatar
Luca Abeni committed
346 347
    if (res < 0) {
        if (errno == EINVAL) {
Luca Abeni's avatar
Luca Abeni committed
348
            av_log(ctx, AV_LOG_ERROR, "Device does not support mmap\n");
Luca Abeni's avatar
Luca Abeni committed
349
        } else {
Luca Abeni's avatar
Luca Abeni committed
350
            av_log(ctx, AV_LOG_ERROR, "ioctl(VIDIOC_REQBUFS)\n");
Luca Abeni's avatar
Luca Abeni committed
351 352
        }

353
        return AVERROR(errno);
Luca Abeni's avatar
Luca Abeni committed
354 355 356
    }

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

359
        return AVERROR(ENOMEM);
Luca Abeni's avatar
Luca Abeni committed
360 361 362 363
    }
    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
364
        av_log(ctx, AV_LOG_ERROR, "Cannot allocate buffer pointers\n");
Luca Abeni's avatar
Luca Abeni committed
365

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

373
        return AVERROR(ENOMEM);
Luca Abeni's avatar
Luca Abeni committed
374 375 376 377 378 379 380 381 382
    }

    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;
383
        res = ioctl(s->fd, VIDIOC_QUERYBUF, &buf);
Luca Abeni's avatar
Luca Abeni committed
384
        if (res < 0) {
Luca Abeni's avatar
Luca Abeni committed
385
            av_log(ctx, AV_LOG_ERROR, "ioctl(VIDIOC_QUERYBUF)\n");
Luca Abeni's avatar
Luca Abeni committed
386

387
            return AVERROR(errno);
Luca Abeni's avatar
Luca Abeni committed
388 389 390
        }

        s->buf_len[i] = buf.length;
391
        if (s->frame_size > 0 && s->buf_len[i] < s->frame_size) {
Luca Barbato's avatar
Luca Barbato committed
392 393 394
            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
395 396 397

            return -1;
        }
Luca Barbato's avatar
Luca Barbato committed
398 399 400 401
        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
402
        if (s->buf_start[i] == MAP_FAILED) {
Luca Abeni's avatar
Luca Abeni committed
403
            av_log(ctx, AV_LOG_ERROR, "mmap: %s\n", strerror(errno));
Luca Abeni's avatar
Luca Abeni committed
404

405
            return AVERROR(errno);
Luca Abeni's avatar
Luca Abeni committed
406 407 408 409 410 411
        }
    }

    return 0;
}

412 413 414 415 416 417
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
418 419
    if (pkt->data == NULL)
        return;
420

421 422 423 424 425 426 427
    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);

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

433 434 435 436 437
    pkt->data = NULL;
    pkt->size = 0;
}

static int mmap_read_frame(AVFormatContext *ctx, AVPacket *pkt)
Luca Abeni's avatar
Luca Abeni committed
438
{
Luca Abeni's avatar
Luca Abeni committed
439
    struct video_data *s = ctx->priv_data;
Luca Abeni's avatar
Luca Abeni committed
440
    struct v4l2_buffer buf;
441
    struct buff_data *buf_descriptor;
Luca Barbato's avatar
Luca Barbato committed
442
    struct pollfd p = { .fd = s->fd, .events = POLLIN };
Luca Abeni's avatar
Luca Abeni committed
443 444 445 446 447 448
    int res;

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

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

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

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

475
        return AVERROR_INVALIDDATA;
476 477
    }

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

491
        return AVERROR(ENOMEM);
Luca Abeni's avatar
Luca Abeni committed
492
    }
493 494 495
    buf_descriptor->fd = s->fd;
    buf_descriptor->index = buf.index;
    pkt->priv = buf_descriptor;
Luca Abeni's avatar
Luca Abeni committed
496 497 498 499

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

Luca Abeni's avatar
Luca Abeni committed
500
static int mmap_start(AVFormatContext *ctx)
Luca Abeni's avatar
Luca Abeni committed
501
{
Luca Abeni's avatar
Luca Abeni committed
502
    struct video_data *s = ctx->priv_data;
Luca Abeni's avatar
Luca Abeni committed
503 504 505 506 507 508 509 510 511 512 513
    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;

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

519
            return AVERROR(errno);
Luca Abeni's avatar
Luca Abeni committed
520 521 522 523
        }
    }

    type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
524
    res = ioctl(s->fd, VIDIOC_STREAMON, &type);
Luca Abeni's avatar
Luca Abeni committed
525
    if (res < 0) {
Luca Barbato's avatar
Luca Barbato committed
526 527
        av_log(ctx, AV_LOG_ERROR, "ioctl(VIDIOC_STREAMON): %s\n",
               strerror(errno));
Luca Abeni's avatar
Luca Abeni committed
528

529
        return AVERROR(errno);
Luca Abeni's avatar
Luca Abeni committed
530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551
    }

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

552
static int v4l2_set_parameters(AVFormatContext *s1, AVFormatParameters *ap)
553 554 555 556
{
    struct video_data *s = s1->priv_data;
    struct v4l2_input input;
    struct v4l2_standard standard;
557 558
    struct v4l2_streamparm streamparm = { 0 };
    struct v4l2_fract *tpf = &streamparm.parm.capture.timeperframe;
559
    int i, ret;
560
    AVRational framerate_q;
561

562 563
    streamparm.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;

Luca Barbato's avatar
Luca Barbato committed
564 565 566 567
    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);
568 569
        return ret;
    }
570

Anton Khirnov's avatar
Anton Khirnov committed
571 572 573 574 575 576 577
    /* 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);
    }
578

Anton Khirnov's avatar
Anton Khirnov committed
579 580 581
    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
582 583
        av_log(s1, AV_LOG_ERROR,
               "The V4L2 driver ioctl set input(%d) failed\n",
Anton Khirnov's avatar
Anton Khirnov committed
584 585 586
                s->channel);
        return AVERROR(EIO);
    }
587

588
    if (s->standard) {
Luca Abeni's avatar
Luca Abeni committed
589
        av_log(s1, AV_LOG_DEBUG, "The V4L2 driver set standard: %s\n",
590
               s->standard);
Luca Abeni's avatar
Luca Abeni committed
591 592 593 594 595
        /* 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
596 597
                av_log(s1, AV_LOG_ERROR,
                       "The V4L2 driver ioctl set standard(%s) failed\n",
598
                       s->standard);
599
                return AVERROR(EIO);
Luca Abeni's avatar
Luca Abeni committed
600 601
            }

602
            if (!av_strcasecmp(standard.name, s->standard)) {
Luca Abeni's avatar
Luca Abeni committed
603 604 605 606
                break;
            }
        }

Luca Barbato's avatar
Luca Barbato committed
607 608
        av_log(s1, AV_LOG_DEBUG,
               "The V4L2 driver set standard: %s, id: %"PRIu64"\n",
609
               s->standard, (uint64_t)standard.id);
Luca Abeni's avatar
Luca Abeni committed
610
        if (ioctl(s->fd, VIDIOC_S_STD, &standard.id) < 0) {
Luca Barbato's avatar
Luca Barbato committed
611 612
            av_log(s1, AV_LOG_ERROR,
                   "The V4L2 driver ioctl set standard(%s) failed\n",
613
                   s->standard);
614
            return AVERROR(EIO);
615
        }
616
    }
617

618
    if (framerate_q.num && framerate_q.den) {
619
        av_log(s1, AV_LOG_DEBUG, "Setting time per frame to %d/%d\n",
620 621 622
               framerate_q.den, framerate_q.num);
        tpf->numerator   = framerate_q.den;
        tpf->denominator = framerate_q.num;
Luca Barbato's avatar
Luca Barbato committed
623

624 625 626
        if (ioctl(s->fd, VIDIOC_S_PARM, &streamparm) != 0) {
            av_log(s1, AV_LOG_ERROR,
                   "ioctl set time per frame(%d/%d) failed\n",
627
                   framerate_q.den, framerate_q.num);
628 629 630
            return AVERROR(EIO);
        }

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

Luca Barbato's avatar
Luca Barbato committed
649 650 651 652
    s->timeout = 100 +
        av_rescale_q(1, s1->streams[0]->codec->time_base,
                        (AVRational){1, 1000});

653 654 655
    return 0;
}

656
static uint32_t device_try_init(AVFormatContext *s1,
657
                                enum PixelFormat pix_fmt,
658 659 660
                                int *width,
                                int *height,
                                enum CodecID *codec_id)
661
{
662
    uint32_t desired_format = fmt_ff2v4l(pix_fmt, s1->video_codec_id);
663 664 665 666 667 668 669

    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++) {
670 671
            if (s1->video_codec_id == CODEC_ID_NONE ||
                fmt_conversion_table[i].codec_id == s1->video_codec_id) {
672 673 674 675 676 677 678 679
                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
680

681 682 683 684 685 686 687 688
    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
689 690 691 692
static int v4l2_read_header(AVFormatContext *s1, AVFormatParameters *ap)
{
    struct video_data *s = s1->priv_data;
    AVStream *st;
693
    int res = 0;
Luca Barbato's avatar
Luca Barbato committed
694
    uint32_t desired_format;
695
    enum CodecID codec_id;
696
    enum PixelFormat pix_fmt = PIX_FMT_NONE;
Luca Abeni's avatar
Luca Abeni committed
697

698
    st = avformat_new_stream(s1, NULL);
Luca Abeni's avatar
Luca Abeni committed
699
    if (!st) {
700 701
        res = AVERROR(ENOMEM);
        goto out;
Luca Abeni's avatar
Luca Abeni committed
702
    }
Luca Barbato's avatar
Luca Barbato committed
703

Luca Barbato's avatar
Luca Barbato committed
704 705 706 707 708 709
    s->fd = device_open(s1);
    if (s->fd < 0) {
        res = s->fd;
        goto out;
    }

Luca Barbato's avatar
Luca Barbato committed
710 711 712 713 714 715
    if (s->list_format) {
        list_formats(s1, s->fd, s->list_format);
        res = AVERROR_EXIT;
        goto out;
    }

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

Luca Barbato's avatar
Luca Barbato committed
718 719 720 721
    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);
722 723
        goto out;
    }
Luca Barbato's avatar
Luca Barbato committed
724 725

    if (s->pixel_format) {
726 727 728 729
        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
730 731 732

        pix_fmt = av_get_pix_fmt(s->pixel_format);

733 734
        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
735 736 737 738 739
                   s->pixel_format);

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

742 743 744
    if (!s->width && !s->height) {
        struct v4l2_format fmt;

Luca Barbato's avatar
Luca Barbato committed
745 746
        av_log(s1, AV_LOG_VERBOSE,
               "Querying the device for the current frame size\n");
747 748
        fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
        if (ioctl(s->fd, VIDIOC_G_FMT, &fmt) < 0) {
Luca Barbato's avatar
Luca Barbato committed
749 750
            av_log(s1, AV_LOG_ERROR, "ioctl(VIDIOC_G_FMT): %s\n",
                   strerror(errno));
751 752
            res = AVERROR(errno);
            goto out;
753
        }
Luca Barbato's avatar
Luca Barbato committed
754

755 756
        s->width  = fmt.fmt.pix.width;
        s->height = fmt.fmt.pix.height;
Luca Barbato's avatar
Luca Barbato committed
757 758
        av_log(s1, AV_LOG_VERBOSE,
               "Setting frame size to %dx%d\n", s->width, s->height);
759 760
    }

Luca Barbato's avatar
Luca Barbato committed
761 762
    desired_format = device_try_init(s1, pix_fmt, &s->width, &s->height,
                                     &codec_id);
Luca Abeni's avatar
Luca Abeni committed
763
    if (desired_format == 0) {
764
        av_log(s1, AV_LOG_ERROR, "Cannot find a proper format for "
765
               "codec_id %d, pix_fmt %d.\n", s1->video_codec_id, pix_fmt);
Luca Abeni's avatar
Luca Abeni committed
766 767
        close(s->fd);

768 769
        res = AVERROR(EIO);
        goto out;
Luca Abeni's avatar
Luca Abeni committed
770
    }
Luca Barbato's avatar
Luca Barbato committed
771

772 773
    if ((res = av_image_check_size(s->width, s->height, 0, s1) < 0))
        goto out;
Luca Barbato's avatar
Luca Barbato committed
774

Luca Abeni's avatar
Luca Abeni committed
775 776
    s->frame_format = desired_format;

777 778
    if ((res = v4l2_set_parameters(s1, ap) < 0))
        goto out;
779

780
    st->codec->pix_fmt = fmt_v4l2ff(desired_format, codec_id);
Luca Barbato's avatar
Luca Barbato committed
781 782 783
    s->frame_size =
        avpicture_get_size(st->codec->pix_fmt, s->width, s->height);

Luca Barbato's avatar
Luca Barbato committed
784 785
    if ((res = mmap_init(s1)) ||
        (res = mmap_start(s1)) < 0) {
Luca Abeni's avatar
Luca Abeni committed
786
        close(s->fd);
787
        goto out;
Luca Abeni's avatar
Luca Abeni committed
788
    }
Luca Barbato's avatar
Luca Barbato committed
789

Luca Abeni's avatar
Luca Abeni committed
790 791
    s->top_field_first = first_field(s->fd);

792
    st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
793
    st->codec->codec_id = codec_id;
Luca Barbato's avatar
Luca Barbato committed
794 795 796
    if (codec_id == CODEC_ID_RAWVIDEO)
        st->codec->codec_tag =
            avcodec_pix_fmt_to_codec_tag(st->codec->pix_fmt);
797 798
    st->codec->width = s->width;
    st->codec->height = s->height;
Luca Abeni's avatar
Luca Abeni committed
799 800
    st->codec->bit_rate = s->frame_size * 1/av_q2d(st->codec->time_base) * 8;

801 802
out:
    return res;
Luca Abeni's avatar
Luca Abeni committed
803 804 805 806 807
}

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

Luca Barbato's avatar
Luca Barbato committed
811 812
    av_init_packet(pkt);
    if ((res = mmap_read_frame(s1, pkt)) < 0) {
813
        return res;
Luca Abeni's avatar
Luca Abeni committed
814 815
    }

Luca Barbato's avatar
Luca Barbato committed
816 817 818
    if (frame && s->interlaced) {
        frame->interlaced_frame = 1;
        frame->top_field_first = s->top_field_first;
Luca Abeni's avatar
Luca Abeni committed
819 820
    }

821
    return pkt->size;
Luca Abeni's avatar
Luca Abeni committed
822 823 824 825 826 827
}

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

Luca Barbato's avatar
Luca Barbato committed
828
    mmap_close(s);
Luca Abeni's avatar
Luca Abeni committed
829 830 831 832 833

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

834 835
#define OFFSET(x) offsetof(struct video_data, x)
#define DEC AV_OPT_FLAG_DECODING_PARAM
836
static const AVOption options[] = {
837 838 839
    { "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 },
840 841
    { "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 },
842
    { "framerate",    "",                                                          OFFSET(framerate),    AV_OPT_TYPE_STRING, {.str = NULL},  0, 0,       DEC },
Luca Barbato's avatar
Luca Barbato committed
843 844 845 846
    { "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" },
847 848 849 850 851 852 853 854 855 856
    { NULL },
};

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

857
AVInputFormat ff_v4l2_demuxer = {
858 859 860 861 862 863 864 865
    .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
866
};