v4l2.c 28.4 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
 *
 * 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
10
 * V4L2_PIX_FMT_* and AV_PIX_FMT_*
Luca Abeni's avatar
Luca Abeni committed
11 12
 *
 *
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
45 46
#include "libavutil/atomic.h"
#include "libavutil/avassert.h"
47
#include "libavutil/imgutils.h"
48
#include "libavutil/internal.h"
49 50
#include "libavutil/log.h"
#include "libavutil/opt.h"
51
#include "libavutil/parseutils.h"
52
#include "libavutil/pixdesc.h"
53
#include "libavutil/avstring.h"
Luca Barbato's avatar
Luca Barbato committed
54
#include "libavutil/mathematics.h"
Luca Abeni's avatar
Luca Abeni committed
55 56 57

static const int desired_video_buffers = 256;

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

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

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

85
struct buff_data {
86
    struct video_data *s;
87 88 89 90
    int index;
    int fd;
};

Luca Abeni's avatar
Luca Abeni committed
91
struct fmt_map {
92
    enum AVPixelFormat ff_fmt;
93
    enum AVCodecID codec_id;
94
    uint32_t v4l2_fmt;
Luca Abeni's avatar
Luca Abeni committed
95 96 97
};

static struct fmt_map fmt_conversion_table[] = {
98
    //ff_fmt           codec_id           v4l2_fmt
99 100 101 102 103 104 105 106 107 108 109 110 111 112 113
    { AV_PIX_FMT_YUV420P, AV_CODEC_ID_RAWVIDEO, V4L2_PIX_FMT_YUV420  },
    { AV_PIX_FMT_YUV422P, AV_CODEC_ID_RAWVIDEO, V4L2_PIX_FMT_YUV422P },
    { AV_PIX_FMT_YUYV422, AV_CODEC_ID_RAWVIDEO, V4L2_PIX_FMT_YUYV    },
    { AV_PIX_FMT_UYVY422, AV_CODEC_ID_RAWVIDEO, V4L2_PIX_FMT_UYVY    },
    { AV_PIX_FMT_YUV411P, AV_CODEC_ID_RAWVIDEO, V4L2_PIX_FMT_YUV411P },
    { AV_PIX_FMT_YUV410P, AV_CODEC_ID_RAWVIDEO, V4L2_PIX_FMT_YUV410  },
    { AV_PIX_FMT_RGB555,  AV_CODEC_ID_RAWVIDEO, V4L2_PIX_FMT_RGB555  },
    { AV_PIX_FMT_RGB565,  AV_CODEC_ID_RAWVIDEO, V4L2_PIX_FMT_RGB565  },
    { AV_PIX_FMT_BGR24,   AV_CODEC_ID_RAWVIDEO, V4L2_PIX_FMT_BGR24   },
    { AV_PIX_FMT_RGB24,   AV_CODEC_ID_RAWVIDEO, V4L2_PIX_FMT_RGB24   },
    { AV_PIX_FMT_BGRA,    AV_CODEC_ID_RAWVIDEO, V4L2_PIX_FMT_BGR32   },
    { AV_PIX_FMT_GRAY8,   AV_CODEC_ID_RAWVIDEO, V4L2_PIX_FMT_GREY    },
    { AV_PIX_FMT_NV12,    AV_CODEC_ID_RAWVIDEO, V4L2_PIX_FMT_NV12    },
    { AV_PIX_FMT_NONE,    AV_CODEC_ID_MJPEG,    V4L2_PIX_FMT_MJPEG   },
    { AV_PIX_FMT_NONE,    AV_CODEC_ID_MJPEG,    V4L2_PIX_FMT_JPEG    },
Luca Abeni's avatar
Luca Abeni committed
114 115
};

Luca Barbato's avatar
Luca Barbato committed
116
static int device_open(AVFormatContext *ctx)
Luca Abeni's avatar
Luca Abeni committed
117 118 119
{
    struct v4l2_capability cap;
    int fd;
120
    int res, err;
121
    int flags = O_RDWR;
Tristan Matthews's avatar
Tristan Matthews committed
122
    char errbuf[128];
Luca Abeni's avatar
Luca Abeni committed
123

124 125 126
    if (ctx->flags & AVFMT_FLAG_NONBLOCK) {
        flags |= O_NONBLOCK;
    }
Luca Barbato's avatar
Luca Barbato committed
127

128
    fd = avpriv_open(ctx->filename, flags);
Luca Abeni's avatar
Luca Abeni committed
129
    if (fd < 0) {
Tristan Matthews's avatar
Tristan Matthews committed
130 131
        err = AVERROR(errno);
        av_strerror(err, errbuf, sizeof(errbuf));
Luca Barbato's avatar
Luca Barbato committed
132

Luca Abeni's avatar
Luca Abeni committed
133
        av_log(ctx, AV_LOG_ERROR, "Cannot open video device %s : %s\n",
Tristan Matthews's avatar
Tristan Matthews committed
134
               ctx->filename, errbuf);
Luca Abeni's avatar
Luca Abeni committed
135

Tristan Matthews's avatar
Tristan Matthews committed
136
        return err;
Luca Abeni's avatar
Luca Abeni committed
137 138 139 140
    }

    res = ioctl(fd, VIDIOC_QUERYCAP, &cap);
    if (res < 0) {
Luca Barbato's avatar
Luca Barbato committed
141
        err = errno;
Tristan Matthews's avatar
Tristan Matthews committed
142
        av_strerror(AVERROR(err), errbuf, sizeof(errbuf));
Luca Abeni's avatar
Luca Abeni committed
143
        av_log(ctx, AV_LOG_ERROR, "ioctl(VIDIOC_QUERYCAP): %s\n",
Tristan Matthews's avatar
Tristan Matthews committed
144
               errbuf);
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
    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
155

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

Luca Barbato's avatar
Luca Barbato committed
159 160 161 162 163 164 165
    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
166 167

    return fd;
Luca Barbato's avatar
Luca Barbato committed
168 169 170 171

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

Luca Barbato's avatar
Luca Barbato committed
174 175
static int device_init(AVFormatContext *ctx, int *width, int *height,
                       uint32_t pix_fmt)
Luca Abeni's avatar
Luca Abeni committed
176
{
Luca Abeni's avatar
Luca Abeni committed
177 178
    struct video_data *s = ctx->priv_data;
    int fd = s->fd;
179
    struct v4l2_format fmt = { .type = V4L2_BUF_TYPE_VIDEO_CAPTURE };
Luca Barbato's avatar
Luca Barbato committed
180 181
    struct v4l2_pix_format *pix = &fmt.fmt.pix;

182
    int res;
Luca Abeni's avatar
Luca Abeni committed
183

Luca Barbato's avatar
Luca Barbato committed
184 185 186 187 188
    pix->width = *width;
    pix->height = *height;
    pix->pixelformat = pix_fmt;
    pix->field = V4L2_FIELD_ANY;

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

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

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

207 208 209 210 211
    if (fmt.fmt.pix.field == V4L2_FIELD_INTERLACED) {
        av_log(ctx, AV_LOG_DEBUG, "The V4L2 driver using the interlaced mode");
        s->interlaced = 1;
    }

212
    return res;
Luca Abeni's avatar
Luca Abeni committed
213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230
}

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

231
static uint32_t fmt_ff2v4l(enum AVPixelFormat pix_fmt, enum AVCodecID codec_id)
Luca Abeni's avatar
Luca Abeni committed
232 233 234
{
    int i;

235
    for (i = 0; i < FF_ARRAY_ELEMS(fmt_conversion_table); i++) {
236
        if ((codec_id == AV_CODEC_ID_NONE ||
237
             fmt_conversion_table[i].codec_id == codec_id) &&
238
            (pix_fmt == AV_PIX_FMT_NONE ||
239
             fmt_conversion_table[i].ff_fmt == pix_fmt)) {
Luca Abeni's avatar
Luca Abeni committed
240 241 242 243 244 245 246
            return fmt_conversion_table[i].v4l2_fmt;
        }
    }

    return 0;
}

247
static enum AVPixelFormat fmt_v4l2ff(uint32_t v4l2_fmt, enum AVCodecID codec_id)
Luca Abeni's avatar
Luca Abeni committed
248 249 250
{
    int i;

251
    for (i = 0; i < FF_ARRAY_ELEMS(fmt_conversion_table); i++) {
252 253
        if (fmt_conversion_table[i].v4l2_fmt == v4l2_fmt &&
            fmt_conversion_table[i].codec_id == codec_id) {
Luca Abeni's avatar
Luca Abeni committed
254 255 256 257
            return fmt_conversion_table[i].ff_fmt;
        }
    }

258
    return AV_PIX_FMT_NONE;
Luca Abeni's avatar
Luca Abeni committed
259 260
}

261
static enum AVCodecID fmt_v4l2codec(uint32_t v4l2_fmt)
262 263 264 265 266 267 268 269 270
{
    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;
        }
    }

271
    return AV_CODEC_ID_NONE;
272 273
}

Luca Barbato's avatar
Luca Barbato committed
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
#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)) {
305
        enum AVCodecID codec_id = fmt_v4l2codec(vfd.pixelformat);
306
        enum AVPixelFormat pix_fmt = fmt_v4l2ff(vfd.pixelformat, codec_id);
Luca Barbato's avatar
Luca Barbato committed
307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325

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

326
#ifdef V4L2_FMT_FLAG_EMULATED
Luca Barbato's avatar
Luca Barbato committed
327 328 329 330
        if (vfd.flags & V4L2_FMT_FLAG_EMULATED) {
            av_log(ctx, AV_LOG_WARNING, "%s", "Emulated");
            continue;
        }
331
#endif
Luca Barbato's avatar
Luca Barbato committed
332 333 334 335 336 337 338
#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
339
static int mmap_init(AVFormatContext *ctx)
Luca Abeni's avatar
Luca Abeni committed
340 341
{
    int i, res;
342 343 344 345 346 347
    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
348

349
    res = ioctl(s->fd, VIDIOC_REQBUFS, &req);
Luca Abeni's avatar
Luca Abeni committed
350 351
    if (res < 0) {
        if (errno == EINVAL) {
Luca Abeni's avatar
Luca Abeni committed
352
            av_log(ctx, AV_LOG_ERROR, "Device does not support mmap\n");
Luca Abeni's avatar
Luca Abeni committed
353
        } else {
Luca Abeni's avatar
Luca Abeni committed
354
            av_log(ctx, AV_LOG_ERROR, "ioctl(VIDIOC_REQBUFS)\n");
Luca Abeni's avatar
Luca Abeni committed
355 356
        }

357
        return AVERROR(errno);
Luca Abeni's avatar
Luca Abeni committed
358 359 360
    }

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

363
        return AVERROR(ENOMEM);
Luca Abeni's avatar
Luca Abeni committed
364 365 366
    }
    s->buffers = req.count;
    s->buf_start = av_malloc(sizeof(void *) * s->buffers);
367
    if (!s->buf_start) {
Luca Abeni's avatar
Luca Abeni committed
368
        av_log(ctx, AV_LOG_ERROR, "Cannot allocate buffer pointers\n");
Luca Abeni's avatar
Luca Abeni committed
369

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

377
        return AVERROR(ENOMEM);
Luca Abeni's avatar
Luca Abeni committed
378 379 380
    }

    for (i = 0; i < req.count; i++) {
381 382 383 384 385
        struct v4l2_buffer buf = {
            .type   = V4L2_BUF_TYPE_VIDEO_CAPTURE,
            .index  = i,
            .memory = V4L2_MEMORY_MMAP
        };
Luca Abeni's avatar
Luca Abeni committed
386

387
        res = ioctl(s->fd, VIDIOC_QUERYBUF, &buf);
Luca Abeni's avatar
Luca Abeni committed
388
        if (res < 0) {
Luca Abeni's avatar
Luca Abeni committed
389
            av_log(ctx, AV_LOG_ERROR, "ioctl(VIDIOC_QUERYBUF)\n");
Luca Abeni's avatar
Luca Abeni committed
390

391
            return AVERROR(errno);
Luca Abeni's avatar
Luca Abeni committed
392 393 394
        }

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

            return -1;
        }
Luca Barbato's avatar
Luca Barbato committed
402 403 404 405
        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
406
        if (s->buf_start[i] == MAP_FAILED) {
Tristan Matthews's avatar
Tristan Matthews committed
407 408 409
            char errbuf[128];
            av_strerror(AVERROR(errno), errbuf, sizeof(errbuf));
            av_log(ctx, AV_LOG_ERROR, "mmap: %s\n", errbuf);
Luca Abeni's avatar
Luca Abeni committed
410

411
            return AVERROR(errno);
Luca Abeni's avatar
Luca Abeni committed
412 413 414 415 416 417
        }
    }

    return 0;
}

418 419 420 421 422 423 424 425
#if FF_API_DESTRUCT_PACKET
static void dummy_release_buffer(AVPacket *pkt)
{
    av_assert0(0);
}
#endif

static void mmap_release_buffer(void *opaque, uint8_t *data)
426
{
427
    struct v4l2_buffer buf = { 0 };
428
    int res, fd;
429 430
    struct buff_data *buf_descriptor = opaque;
    struct video_data *s = buf_descriptor->s;
Tristan Matthews's avatar
Tristan Matthews committed
431
    char errbuf[128];
432

433 434 435 436 437 438
    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);

439
    res = ioctl(fd, VIDIOC_QBUF, &buf);
Tristan Matthews's avatar
Tristan Matthews committed
440 441
    if (res < 0) {
        av_strerror(AVERROR(errno), errbuf, sizeof(errbuf));
Luca Barbato's avatar
Luca Barbato committed
442
        av_log(NULL, AV_LOG_ERROR, "ioctl(VIDIOC_QBUF): %s\n",
Tristan Matthews's avatar
Tristan Matthews committed
443 444
               errbuf);
    }
445
    avpriv_atomic_int_add_and_fetch(&s->buffers_queued, 1);
446 447 448
}

static int mmap_read_frame(AVFormatContext *ctx, AVPacket *pkt)
Luca Abeni's avatar
Luca Abeni committed
449
{
Luca Abeni's avatar
Luca Abeni committed
450
    struct video_data *s = ctx->priv_data;
451 452 453 454
    struct v4l2_buffer buf = {
        .type   = V4L2_BUF_TYPE_VIDEO_CAPTURE,
        .memory = V4L2_MEMORY_MMAP
    };
Luca Barbato's avatar
Luca Barbato committed
455
    struct pollfd p = { .fd = s->fd, .events = POLLIN };
Luca Abeni's avatar
Luca Abeni committed
456 457
    int res;

Luca Barbato's avatar
Luca Barbato committed
458 459 460 461 462 463 464
    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
465
    /* FIXME: Some special treatment might be needed in case of loss of signal... */
466
    while ((res = ioctl(s->fd, VIDIOC_DQBUF, &buf)) < 0 && (errno == EINTR));
Luca Abeni's avatar
Luca Abeni committed
467
    if (res < 0) {
Tristan Matthews's avatar
Tristan Matthews committed
468
        char errbuf[128];
469 470 471 472 473
        if (errno == EAGAIN) {
            pkt->size = 0;

            return AVERROR(EAGAIN);
        }
Tristan Matthews's avatar
Tristan Matthews committed
474
        av_strerror(AVERROR(errno), errbuf, sizeof(errbuf));
Luca Barbato's avatar
Luca Barbato committed
475
        av_log(ctx, AV_LOG_ERROR, "ioctl(VIDIOC_DQBUF): %s\n",
Tristan Matthews's avatar
Tristan Matthews committed
476
               errbuf);
Luca Abeni's avatar
Luca Abeni committed
477

478
        return AVERROR(errno);
Luca Abeni's avatar
Luca Abeni committed
479
    }
480 481 482 483 484

    if (buf.index >= s->buffers) {
        av_log(ctx, AV_LOG_ERROR, "Invalid buffer index received.\n");
        return AVERROR(EINVAL);
    }
485 486 487
    avpriv_atomic_int_add_and_fetch(&s->buffers_queued, -1);
    // always keep at least one buffer queued
    av_assert0(avpriv_atomic_int_get(&s->buffers_queued) >= 1);
488

489
    if (s->frame_size > 0 && buf.bytesused != s->frame_size) {
Luca Barbato's avatar
Luca Barbato committed
490 491 492
        av_log(ctx, AV_LOG_ERROR,
               "The v4l2 frame is %d bytes, but %d bytes are expected\n",
               buf.bytesused, s->frame_size);
493

494
        return AVERROR_INVALIDDATA;
495 496
    }

Luca Abeni's avatar
Luca Abeni committed
497
    /* Image is at s->buff_start[buf.index] */
498
    if (avpriv_atomic_int_get(&s->buffers_queued) == FFMAX(s->buffers / 8, 1)) {
Diego Biurrun's avatar
Diego Biurrun committed
499
        /* when we start getting low on queued buffers, fall back on copying data */
500 501 502 503 504 505 506
        res = av_new_packet(pkt, buf.bytesused);
        if (res < 0) {
            av_log(ctx, AV_LOG_ERROR, "Error allocating a packet.\n");
            return res;
        }
        memcpy(pkt->data, s->buf_start[buf.index], buf.bytesused);

507
        res = ioctl(s->fd, VIDIOC_QBUF, &buf);
508 509 510 511 512 513 514 515
        if (res < 0) {
            av_log(ctx, AV_LOG_ERROR, "ioctl(VIDIOC_QBUF)\n");
            av_free_packet(pkt);
            return AVERROR(errno);
        }
        avpriv_atomic_int_add_and_fetch(&s->buffers_queued, 1);
    } else {
        struct buff_data *buf_descriptor;
Luca Abeni's avatar
Luca Abeni committed
516

517 518 519
        pkt->data     = s->buf_start[buf.index];
        pkt->size     = buf.bytesused;
#if FF_API_DESTRUCT_PACKET
520
FF_DISABLE_DEPRECATION_WARNINGS
521
        pkt->destruct = dummy_release_buffer;
522
FF_ENABLE_DEPRECATION_WARNINGS
523 524 525
#endif

        buf_descriptor = av_malloc(sizeof(struct buff_data));
526
        if (!buf_descriptor) {
527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544
            /* Something went wrong... Since av_malloc() failed, we cannot even
             * allocate a buffer for memcpying into it
             */
            av_log(ctx, AV_LOG_ERROR, "Failed to allocate a buffer descriptor\n");
            res = ioctl(s->fd, VIDIOC_QBUF, &buf);

            return AVERROR(ENOMEM);
        }
        buf_descriptor->fd    = s->fd;
        buf_descriptor->index = buf.index;
        buf_descriptor->s     = s;

        pkt->buf = av_buffer_create(pkt->data, pkt->size, mmap_release_buffer,
                                    buf_descriptor, 0);
        if (!pkt->buf) {
            av_freep(&buf_descriptor);
            return AVERROR(ENOMEM);
        }
Luca Abeni's avatar
Luca Abeni committed
545
    }
546
    pkt->pts = buf.timestamp.tv_sec * INT64_C(1000000) + buf.timestamp.tv_usec;
Luca Abeni's avatar
Luca Abeni committed
547 548 549 550

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

Luca Abeni's avatar
Luca Abeni committed
551
static int mmap_start(AVFormatContext *ctx)
Luca Abeni's avatar
Luca Abeni committed
552
{
Luca Abeni's avatar
Luca Abeni committed
553
    struct video_data *s = ctx->priv_data;
Luca Abeni's avatar
Luca Abeni committed
554
    enum v4l2_buf_type type;
Tristan Matthews's avatar
Tristan Matthews committed
555 556
    int i, res, err;
    char errbuf[128];
Luca Abeni's avatar
Luca Abeni committed
557 558

    for (i = 0; i < s->buffers; i++) {
559 560 561 562 563
        struct v4l2_buffer buf = {
            .type   = V4L2_BUF_TYPE_VIDEO_CAPTURE,
            .index  = i,
            .memory = V4L2_MEMORY_MMAP
        };
Luca Abeni's avatar
Luca Abeni committed
564

565
        res = ioctl(s->fd, VIDIOC_QBUF, &buf);
Luca Abeni's avatar
Luca Abeni committed
566
        if (res < 0) {
Tristan Matthews's avatar
Tristan Matthews committed
567 568
            err = AVERROR(errno);
            av_strerror(err, errbuf, sizeof(errbuf));
Luca Barbato's avatar
Luca Barbato committed
569
            av_log(ctx, AV_LOG_ERROR, "ioctl(VIDIOC_QBUF): %s\n",
Tristan Matthews's avatar
Tristan Matthews committed
570
                   errbuf);
Luca Abeni's avatar
Luca Abeni committed
571

Tristan Matthews's avatar
Tristan Matthews committed
572
            return err;
Luca Abeni's avatar
Luca Abeni committed
573 574
        }
    }
575
    s->buffers_queued = s->buffers;
Luca Abeni's avatar
Luca Abeni committed
576 577

    type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
578
    res = ioctl(s->fd, VIDIOC_STREAMON, &type);
Luca Abeni's avatar
Luca Abeni committed
579
    if (res < 0) {
Tristan Matthews's avatar
Tristan Matthews committed
580 581
        err = AVERROR(errno);
        av_strerror(err, errbuf, sizeof(errbuf));
Luca Barbato's avatar
Luca Barbato committed
582
        av_log(ctx, AV_LOG_ERROR, "ioctl(VIDIOC_STREAMON): %s\n",
Tristan Matthews's avatar
Tristan Matthews committed
583
               errbuf);
Luca Abeni's avatar
Luca Abeni committed
584

Tristan Matthews's avatar
Tristan Matthews committed
585
        return err;
Luca Abeni's avatar
Luca Abeni committed
586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607
    }

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

608
static int v4l2_set_parameters(AVFormatContext *s1)
609 610
{
    struct video_data *s = s1->priv_data;
611 612
    struct v4l2_input input = { 0 };
    struct v4l2_standard standard = { 0 };
613 614
    struct v4l2_streamparm streamparm = { 0 };
    struct v4l2_fract *tpf = &streamparm.parm.capture.timeperframe;
615
    AVRational framerate_q = { 0 };
616
    int i, ret;
617

618 619
    streamparm.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;

Luca Barbato's avatar
Luca Barbato committed
620 621 622 623
    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);
624 625
        return ret;
    }
626

Anton Khirnov's avatar
Anton Khirnov committed
627 628 629 630 631 632
    /* 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);
    }
633

Anton Khirnov's avatar
Anton Khirnov committed
634 635 636
    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
637 638
        av_log(s1, AV_LOG_ERROR,
               "The V4L2 driver ioctl set input(%d) failed\n",
Anton Khirnov's avatar
Anton Khirnov committed
639 640 641
                s->channel);
        return AVERROR(EIO);
    }
642

643
    if (s->standard) {
Luca Abeni's avatar
Luca Abeni committed
644
        av_log(s1, AV_LOG_DEBUG, "The V4L2 driver set standard: %s\n",
645
               s->standard);
Luca Abeni's avatar
Luca Abeni committed
646 647 648 649
        /* 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
650 651
                av_log(s1, AV_LOG_ERROR,
                       "The V4L2 driver ioctl set standard(%s) failed\n",
652
                       s->standard);
653
                return AVERROR(EIO);
Luca Abeni's avatar
Luca Abeni committed
654 655
            }

656
            if (!av_strcasecmp(standard.name, s->standard)) {
Luca Abeni's avatar
Luca Abeni committed
657 658 659 660
                break;
            }
        }

Luca Barbato's avatar
Luca Barbato committed
661 662
        av_log(s1, AV_LOG_DEBUG,
               "The V4L2 driver set standard: %s, id: %"PRIu64"\n",
663
               s->standard, (uint64_t)standard.id);
Luca Abeni's avatar
Luca Abeni committed
664
        if (ioctl(s->fd, VIDIOC_S_STD, &standard.id) < 0) {
Luca Barbato's avatar
Luca Barbato committed
665 666
            av_log(s1, AV_LOG_ERROR,
                   "The V4L2 driver ioctl set standard(%s) failed\n",
667
                   s->standard);
668
            return AVERROR(EIO);
669
        }
670
    }
671

672
    if (framerate_q.num && framerate_q.den) {
673
        av_log(s1, AV_LOG_DEBUG, "Setting time per frame to %d/%d\n",
674 675 676
               framerate_q.den, framerate_q.num);
        tpf->numerator   = framerate_q.den;
        tpf->denominator = framerate_q.num;
Luca Barbato's avatar
Luca Barbato committed
677

678 679 680
        if (ioctl(s->fd, VIDIOC_S_PARM, &streamparm) != 0) {
            av_log(s1, AV_LOG_ERROR,
                   "ioctl set time per frame(%d/%d) failed\n",
681
                   framerate_q.den, framerate_q.num);
682 683 684
            return AVERROR(EIO);
        }

685 686
        if (framerate_q.num != tpf->denominator ||
            framerate_q.den != tpf->numerator) {
687
            av_log(s1, AV_LOG_INFO,
Luca Barbato's avatar
Luca Barbato committed
688 689
                   "The driver changed the time per frame from "
                   "%d/%d to %d/%d\n",
690
                   framerate_q.den, framerate_q.num,
691 692
                   tpf->numerator, tpf->denominator);
        }
693 694
    } else {
        if (ioctl(s->fd, VIDIOC_G_PARM, &streamparm) != 0) {
Tristan Matthews's avatar
Tristan Matthews committed
695 696
            char errbuf[128];
            av_strerror(AVERROR(errno), errbuf, sizeof(errbuf));
Luca Barbato's avatar
Luca Barbato committed
697
            av_log(s1, AV_LOG_ERROR, "ioctl(VIDIOC_G_PARM): %s\n",
Tristan Matthews's avatar
Tristan Matthews committed
698
                   errbuf);
699 700
            return AVERROR(errno);
        }
701
    }
702 703
    s1->streams[0]->avg_frame_rate.num = tpf->denominator;
    s1->streams[0]->avg_frame_rate.den = tpf->numerator;
704

Luca Barbato's avatar
Luca Barbato committed
705
    s->timeout = 100 +
706
        av_rescale_q(1, s1->streams[0]->avg_frame_rate,
Luca Barbato's avatar
Luca Barbato committed
707 708
                        (AVRational){1, 1000});

709 710 711
    return 0;
}

712
static uint32_t device_try_init(AVFormatContext *s1,
713
                                enum AVPixelFormat pix_fmt,
714 715
                                int *width,
                                int *height,
716
                                enum AVCodecID *codec_id)
717
{
718
    uint32_t desired_format = fmt_ff2v4l(pix_fmt, s1->video_codec_id);
719 720 721 722 723 724 725

    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++) {
726
            if (s1->video_codec_id == AV_CODEC_ID_NONE ||
727
                fmt_conversion_table[i].codec_id == s1->video_codec_id) {
728 729 730 731 732 733 734 735
                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
736

737 738
    if (desired_format != 0) {
        *codec_id = fmt_v4l2codec(desired_format);
739
        assert(*codec_id != AV_CODEC_ID_NONE);
740 741 742 743 744
    }

    return desired_format;
}

745
static int v4l2_read_header(AVFormatContext *s1)
Luca Abeni's avatar
Luca Abeni committed
746 747 748
{
    struct video_data *s = s1->priv_data;
    AVStream *st;
749
    int res = 0;
Luca Barbato's avatar
Luca Barbato committed
750
    uint32_t desired_format;
751
    enum AVCodecID codec_id;
752
    enum AVPixelFormat pix_fmt = AV_PIX_FMT_NONE;
Luca Abeni's avatar
Luca Abeni committed
753

754
    st = avformat_new_stream(s1, NULL);
755 756
    if (!st)
        return AVERROR(ENOMEM);
Luca Barbato's avatar
Luca Barbato committed
757

Luca Barbato's avatar
Luca Barbato committed
758
    s->fd = device_open(s1);
759 760
    if (s->fd < 0)
        return s->fd;
Luca Barbato's avatar
Luca Barbato committed
761

Luca Barbato's avatar
Luca Barbato committed
762 763
    if (s->list_format) {
        list_formats(s1, s->fd, s->list_format);
764
        return AVERROR_EXIT;
Luca Barbato's avatar
Luca Barbato committed
765 766
    }

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

Luca Barbato's avatar
Luca Barbato committed
769 770 771 772
    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);
773
        return res;
774
    }
Luca Barbato's avatar
Luca Barbato committed
775 776

    if (s->pixel_format) {
777 778 779 780
        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
781 782 783

        pix_fmt = av_get_pix_fmt(s->pixel_format);

784
        if (pix_fmt == AV_PIX_FMT_NONE && !codec) {
785
            av_log(s1, AV_LOG_ERROR, "No such input format: %s.\n",
Luca Barbato's avatar
Luca Barbato committed
786 787
                   s->pixel_format);

788
            return AVERROR(EINVAL);
Luca Barbato's avatar
Luca Barbato committed
789
        }
790
    }
Luca Abeni's avatar
Luca Abeni committed
791

792 793 794
    if (!s->width && !s->height) {
        struct v4l2_format fmt;

Luca Barbato's avatar
Luca Barbato committed
795 796
        av_log(s1, AV_LOG_VERBOSE,
               "Querying the device for the current frame size\n");
797 798
        fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
        if (ioctl(s->fd, VIDIOC_G_FMT, &fmt) < 0) {
Tristan Matthews's avatar
Tristan Matthews committed
799 800
            char errbuf[128];
            av_strerror(AVERROR(errno), errbuf, sizeof(errbuf));
Luca Barbato's avatar
Luca Barbato committed
801
            av_log(s1, AV_LOG_ERROR, "ioctl(VIDIOC_G_FMT): %s\n",
Tristan Matthews's avatar
Tristan Matthews committed
802
                   errbuf);
803
            return AVERROR(errno);
804
        }
Luca Barbato's avatar
Luca Barbato committed
805

806 807
        s->width  = fmt.fmt.pix.width;
        s->height = fmt.fmt.pix.height;
Luca Barbato's avatar
Luca Barbato committed
808 809
        av_log(s1, AV_LOG_VERBOSE,
               "Setting frame size to %dx%d\n", s->width, s->height);
810 811
    }

Luca Barbato's avatar
Luca Barbato committed
812 813
    desired_format = device_try_init(s1, pix_fmt, &s->width, &s->height,
                                     &codec_id);
Luca Abeni's avatar
Luca Abeni committed
814
    if (desired_format == 0) {
815
        av_log(s1, AV_LOG_ERROR, "Cannot find a proper format for "
816
               "codec_id %d, pix_fmt %d.\n", s1->video_codec_id, pix_fmt);
Luca Abeni's avatar
Luca Abeni committed
817 818
        close(s->fd);

819
        return AVERROR(EIO);
Luca Abeni's avatar
Luca Abeni committed
820
    }
Luca Barbato's avatar
Luca Barbato committed
821

822
    if ((res = av_image_check_size(s->width, s->height, 0,