v4l2.c 27.7 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 49
#include "libavutil/log.h"
#include "libavutil/opt.h"
50
#include "libavutil/parseutils.h"
51
#include "libavutil/pixdesc.h"
52
#include "libavutil/avstring.h"
Luca Barbato's avatar
Luca Barbato committed
53
#include "libavutil/mathematics.h"
Luca Abeni's avatar
Luca Abeni committed
54 55 56

static const int desired_video_buffers = 256;

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

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

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

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

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

static struct fmt_map fmt_conversion_table[] = {
97
    //ff_fmt           codec_id           v4l2_fmt
98 99 100 101 102 103 104 105 106 107 108 109 110 111 112
    { 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
113 114
};

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

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

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

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

Luca Barbato's avatar
Luca Barbato committed
133
        return AVERROR(err);
Luca Abeni's avatar
Luca Abeni committed
134 135 136 137
    }

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

Luca Barbato's avatar
Luca Barbato committed
142
        goto fail;
Luca Abeni's avatar
Luca Abeni committed
143
    }
Luca Barbato's avatar
Luca Barbato committed
144

Luca Barbato's avatar
Luca Barbato committed
145 146 147 148 149 150
    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
151

Luca Barbato's avatar
Luca Barbato committed
152
        goto fail;
Luca Abeni's avatar
Luca Abeni committed
153
    }
Luca Barbato's avatar
Luca Barbato committed
154

Luca Barbato's avatar
Luca Barbato committed
155 156 157 158 159 160 161
    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
162 163

    return fd;
Luca Barbato's avatar
Luca Barbato committed
164 165 166 167

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

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

178
    int res;
Luca Abeni's avatar
Luca Abeni committed
179

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 AVPixelFormat pix_fmt, enum AVCodecID 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
        if ((codec_id == AV_CODEC_ID_NONE ||
233
             fmt_conversion_table[i].codec_id == codec_id) &&
234
            (pix_fmt == AV_PIX_FMT_NONE ||
235
             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 AVPixelFormat fmt_v4l2ff(uint32_t v4l2_fmt, enum AVCodecID 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 AV_PIX_FMT_NONE;
Luca Abeni's avatar
Luca Abeni committed
255 256
}

257
static enum AVCodecID fmt_v4l2codec(uint32_t v4l2_fmt)
258 259 260 261 262 263 264 265 266
{
    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;
        }
    }

267
    return AV_CODEC_ID_NONE;
268 269
}

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

        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 337
{
    int i, res;
338 339 340 341 342 343
    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
344

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
    }

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

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 418 419
#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)
420
{
421
    struct v4l2_buffer buf = { 0 };
422
    int res, fd;
423 424
    struct buff_data *buf_descriptor = opaque;
    struct video_data *s = buf_descriptor->s;
425

426 427 428 429 430 431
    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);

432
    res = ioctl(fd, VIDIOC_QBUF, &buf);
Luca Barbato's avatar
Luca Barbato committed
433 434 435
    if (res < 0)
        av_log(NULL, AV_LOG_ERROR, "ioctl(VIDIOC_QBUF): %s\n",
               strerror(errno));
436
    avpriv_atomic_int_add_and_fetch(&s->buffers_queued, 1);
437 438 439
}

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

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 470 471 472 473

    if (buf.index >= s->buffers) {
        av_log(ctx, AV_LOG_ERROR, "Invalid buffer index received.\n");
        return AVERROR(EINVAL);
    }
474 475 476
    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);
477

478
    if (s->frame_size > 0 && buf.bytesused != s->frame_size) {
Luca Barbato's avatar
Luca Barbato committed
479 480 481
        av_log(ctx, AV_LOG_ERROR,
               "The v4l2 frame is %d bytes, but %d bytes are expected\n",
               buf.bytesused, s->frame_size);
482

483
        return AVERROR_INVALIDDATA;
484 485
    }

Luca Abeni's avatar
Luca Abeni committed
486
    /* Image is at s->buff_start[buf.index] */
487 488 489 490 491 492 493 494 495
    if (avpriv_atomic_int_get(&s->buffers_queued) == FFMAX(s->buffers / 8, 1)) {
        /* when we start getting low on queued buffers, fallback to copying data */
        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);

496
        res = ioctl(s->fd, VIDIOC_QBUF, &buf);
497 498 499 500 501 502 503 504
        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
505

506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531
        pkt->data     = s->buf_start[buf.index];
        pkt->size     = buf.bytesused;
#if FF_API_DESTRUCT_PACKET
        pkt->destruct = dummy_release_buffer;
#endif

        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 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
532
    }
533
    pkt->pts = buf.timestamp.tv_sec * INT64_C(1000000) + buf.timestamp.tv_usec;
Luca Abeni's avatar
Luca Abeni committed
534 535 536 537

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

Luca Abeni's avatar
Luca Abeni committed
538
static int mmap_start(AVFormatContext *ctx)
Luca Abeni's avatar
Luca Abeni committed
539
{
Luca Abeni's avatar
Luca Abeni committed
540
    struct video_data *s = ctx->priv_data;
Luca Abeni's avatar
Luca Abeni committed
541 542 543 544
    enum v4l2_buf_type type;
    int i, res;

    for (i = 0; i < s->buffers; i++) {
545 546 547 548 549
        struct v4l2_buffer buf = {
            .type   = V4L2_BUF_TYPE_VIDEO_CAPTURE,
            .index  = i,
            .memory = V4L2_MEMORY_MMAP
        };
Luca Abeni's avatar
Luca Abeni committed
550

551
        res = ioctl(s->fd, VIDIOC_QBUF, &buf);
Luca Abeni's avatar
Luca Abeni committed
552
        if (res < 0) {
Luca Barbato's avatar
Luca Barbato committed
553 554
            av_log(ctx, AV_LOG_ERROR, "ioctl(VIDIOC_QBUF): %s\n",
                   strerror(errno));
Luca Abeni's avatar
Luca Abeni committed
555

556
            return AVERROR(errno);
Luca Abeni's avatar
Luca Abeni committed
557 558
        }
    }
559
    s->buffers_queued = s->buffers;
Luca Abeni's avatar
Luca Abeni committed
560 561

    type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
562
    res = ioctl(s->fd, VIDIOC_STREAMON, &type);
Luca Abeni's avatar
Luca Abeni committed
563
    if (res < 0) {
Luca Barbato's avatar
Luca Barbato committed
564 565
        av_log(ctx, AV_LOG_ERROR, "ioctl(VIDIOC_STREAMON): %s\n",
               strerror(errno));
Luca Abeni's avatar
Luca Abeni committed
566

567
        return AVERROR(errno);
Luca Abeni's avatar
Luca Abeni committed
568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589
    }

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

590
static int v4l2_set_parameters(AVFormatContext *s1)
591 592
{
    struct video_data *s = s1->priv_data;
593 594
    struct v4l2_input input = { 0 };
    struct v4l2_standard standard = { 0 };
595 596
    struct v4l2_streamparm streamparm = { 0 };
    struct v4l2_fract *tpf = &streamparm.parm.capture.timeperframe;
597
    AVRational framerate_q = { 0 };
598
    int i, ret;
599

600 601
    streamparm.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;

Luca Barbato's avatar
Luca Barbato committed
602 603 604 605
    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);
606 607
        return ret;
    }
608

Anton Khirnov's avatar
Anton Khirnov committed
609 610 611 612 613 614
    /* 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);
    }
615

Anton Khirnov's avatar
Anton Khirnov committed
616 617 618
    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
619 620
        av_log(s1, AV_LOG_ERROR,
               "The V4L2 driver ioctl set input(%d) failed\n",
Anton Khirnov's avatar
Anton Khirnov committed
621 622 623
                s->channel);
        return AVERROR(EIO);
    }
624

625
    if (s->standard) {
Luca Abeni's avatar
Luca Abeni committed
626
        av_log(s1, AV_LOG_DEBUG, "The V4L2 driver set standard: %s\n",
627
               s->standard);
Luca Abeni's avatar
Luca Abeni committed
628 629 630 631
        /* 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
632 633
                av_log(s1, AV_LOG_ERROR,
                       "The V4L2 driver ioctl set standard(%s) failed\n",
634
                       s->standard);
635
                return AVERROR(EIO);
Luca Abeni's avatar
Luca Abeni committed
636 637
            }

638
            if (!av_strcasecmp(standard.name, s->standard)) {
Luca Abeni's avatar
Luca Abeni committed
639 640 641 642
                break;
            }
        }

Luca Barbato's avatar
Luca Barbato committed
643 644
        av_log(s1, AV_LOG_DEBUG,
               "The V4L2 driver set standard: %s, id: %"PRIu64"\n",
645
               s->standard, (uint64_t)standard.id);
Luca Abeni's avatar
Luca Abeni committed
646
        if (ioctl(s->fd, VIDIOC_S_STD, &standard.id) < 0) {
Luca Barbato's avatar
Luca Barbato committed
647 648
            av_log(s1, AV_LOG_ERROR,
                   "The V4L2 driver ioctl set standard(%s) failed\n",
649
                   s->standard);
650
            return AVERROR(EIO);
651
        }
652
    }
653

654
    if (framerate_q.num && framerate_q.den) {
655
        av_log(s1, AV_LOG_DEBUG, "Setting time per frame to %d/%d\n",
656 657 658
               framerate_q.den, framerate_q.num);
        tpf->numerator   = framerate_q.den;
        tpf->denominator = framerate_q.num;
Luca Barbato's avatar
Luca Barbato committed
659

660 661 662
        if (ioctl(s->fd, VIDIOC_S_PARM, &streamparm) != 0) {
            av_log(s1, AV_LOG_ERROR,
                   "ioctl set time per frame(%d/%d) failed\n",
663
                   framerate_q.den, framerate_q.num);
664 665 666
            return AVERROR(EIO);
        }

667 668
        if (framerate_q.num != tpf->denominator ||
            framerate_q.den != tpf->numerator) {
669
            av_log(s1, AV_LOG_INFO,
Luca Barbato's avatar
Luca Barbato committed
670 671
                   "The driver changed the time per frame from "
                   "%d/%d to %d/%d\n",
672
                   framerate_q.den, framerate_q.num,
673 674
                   tpf->numerator, tpf->denominator);
        }
675 676
    } else {
        if (ioctl(s->fd, VIDIOC_G_PARM, &streamparm) != 0) {
Luca Barbato's avatar
Luca Barbato committed
677 678
            av_log(s1, AV_LOG_ERROR, "ioctl(VIDIOC_G_PARM): %s\n",
                   strerror(errno));
679 680
            return AVERROR(errno);
        }
681
    }
682 683
    s1->streams[0]->avg_frame_rate.num = tpf->denominator;
    s1->streams[0]->avg_frame_rate.den = tpf->numerator;
684

Luca Barbato's avatar
Luca Barbato committed
685
    s->timeout = 100 +
686
        av_rescale_q(1, s1->streams[0]->avg_frame_rate,
Luca Barbato's avatar
Luca Barbato committed
687 688
                        (AVRational){1, 1000});

689 690 691
    return 0;
}

692
static uint32_t device_try_init(AVFormatContext *s1,
693
                                enum AVPixelFormat pix_fmt,
694 695
                                int *width,
                                int *height,
696
                                enum AVCodecID *codec_id)
697
{
698
    uint32_t desired_format = fmt_ff2v4l(pix_fmt, s1->video_codec_id);
699 700 701 702 703 704 705

    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++) {
706
            if (s1->video_codec_id == AV_CODEC_ID_NONE ||
707
                fmt_conversion_table[i].codec_id == s1->video_codec_id) {
708 709 710 711 712 713 714 715
                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
716

717 718
    if (desired_format != 0) {
        *codec_id = fmt_v4l2codec(desired_format);
719
        assert(*codec_id != AV_CODEC_ID_NONE);
720 721 722 723 724
    }

    return desired_format;
}

725
static int v4l2_read_header(AVFormatContext *s1)
Luca Abeni's avatar
Luca Abeni committed
726 727 728
{
    struct video_data *s = s1->priv_data;
    AVStream *st;
729
    int res = 0;
Luca Barbato's avatar
Luca Barbato committed
730
    uint32_t desired_format;
731
    enum AVCodecID codec_id;
732
    enum AVPixelFormat pix_fmt = AV_PIX_FMT_NONE;
Luca Abeni's avatar
Luca Abeni committed
733

734
    st = avformat_new_stream(s1, NULL);
735 736
    if (!st)
        return AVERROR(ENOMEM);
Luca Barbato's avatar
Luca Barbato committed
737

Luca Barbato's avatar
Luca Barbato committed
738
    s->fd = device_open(s1);
739 740
    if (s->fd < 0)
        return s->fd;
Luca Barbato's avatar
Luca Barbato committed
741

Luca Barbato's avatar
Luca Barbato committed
742 743
    if (s->list_format) {
        list_formats(s1, s->fd, s->list_format);
744
        return AVERROR_EXIT;
Luca Barbato's avatar
Luca Barbato committed
745 746
    }

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

Luca Barbato's avatar
Luca Barbato committed
749 750 751 752
    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);
753
        return res;
754
    }
Luca Barbato's avatar
Luca Barbato committed
755 756

    if (s->pixel_format) {
757 758 759 760
        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
761 762 763

        pix_fmt = av_get_pix_fmt(s->pixel_format);

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

768
            return AVERROR(EINVAL);
Luca Barbato's avatar
Luca Barbato committed
769
        }
770
    }
Luca Abeni's avatar
Luca Abeni committed
771

772 773 774
    if (!s->width && !s->height) {
        struct v4l2_format fmt;

Luca Barbato's avatar
Luca Barbato committed
775 776
        av_log(s1, AV_LOG_VERBOSE,
               "Querying the device for the current frame size\n");
777 778
        fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
        if (ioctl(s->fd, VIDIOC_G_FMT, &fmt) < 0) {
Luca Barbato's avatar
Luca Barbato committed
779 780
            av_log(s1, AV_LOG_ERROR, "ioctl(VIDIOC_G_FMT): %s\n",
                   strerror(errno));
781
            return AVERROR(errno);
782
        }
Luca Barbato's avatar
Luca Barbato committed
783

784 785
        s->width  = fmt.fmt.pix.width;
        s->height = fmt.fmt.pix.height;
Luca Barbato's avatar
Luca Barbato committed
786 787
        av_log(s1, AV_LOG_VERBOSE,
               "Setting frame size to %dx%d\n", s->width, s->height);
788 789
    }

Luca Barbato's avatar
Luca Barbato committed
790 791
    desired_format = device_try_init(s1, pix_fmt, &s->width, &s->height,
                                     &codec_id);
Luca Abeni's avatar
Luca Abeni committed
792
    if (desired_format == 0) {
793
        av_log(s1, AV_LOG_ERROR, "Cannot find a proper format for "
794
               "codec_id %d, pix_fmt %d.\n", s1->video_codec_id, pix_fmt);
Luca Abeni's avatar
Luca Abeni committed
795 796
        close(s->fd);

797
        return AVERROR(EIO);
Luca Abeni's avatar
Luca Abeni committed
798
    }
Luca Barbato's avatar
Luca Barbato committed
799

800
    if ((res = av_image_check_size(s->width, s->height, 0, s1) < 0))
801
        return res;
Luca Barbato's avatar
Luca Barbato committed
802

Luca Abeni's avatar
Luca Abeni committed
803 804
    s->frame_format = desired_format;

805
    if ((res = v4l2_set_parameters(s1) < 0))
806
        return res;
807

808
    st->codec->pix_fmt = fmt_v4l2ff(desired_format, codec_id);
Luca Barbato's avatar
Luca Barbato committed
809 810 811
    s->frame_size =
        avpicture_get_size(st->codec->pix_fmt, s->width, s->height);

Luca Barbato's avatar
Luca Barbato committed
812 813
    if ((res = mmap_init(s1)) ||
        (res = mmap_start(s1)) < 0) {
Luca Abeni's avatar
Luca Abeni committed
814
        close(s->fd);
815
        return res;
Luca Abeni's avatar
Luca Abeni committed
816
    }
Luca Barbato's avatar
Luca Barbato committed
817

Luca Abeni's avatar
Luca Abeni committed
818 819
    s->top_field_first = first_field(s->fd);

820
    st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
821
    st->codec->codec_id = codec_id;
822
    if (codec_id == AV_CODEC_ID_RAWVIDEO)
Luca Barbato's avatar
Luca Barbato committed
823 824
        st->codec->codec_tag =
            avcodec_pix_fmt_to_codec_tag(st->codec->pix_fmt);
825 826
    st->codec->width = s->width;
    st->codec->height = s->height;
827
    st->codec->bit_rate = s->frame_size * av_q2d(st->avg_frame_rate) * 8;
Luca Abeni's avatar
Luca Abeni committed
828

829
    return 0;
Luca Abeni's avatar
Luca Abeni committed
830 831 832 833 834
}

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