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

static const int desired_video_buffers = 256;

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

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

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

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

Luca Abeni's avatar
Luca Abeni committed
86
struct fmt_map {
87
    enum AVPixelFormat ff_fmt;
88
    enum AVCodecID codec_id;
89
    uint32_t v4l2_fmt;
Luca Abeni's avatar
Luca Abeni committed
90 91 92
};

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Luca Barbato's avatar
Luca Barbato committed
176 177 178 179 180
    pix->width = *width;
    pix->height = *height;
    pix->pixelformat = pix_fmt;
    pix->field = V4L2_FIELD_ANY;

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

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

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

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

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

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

223
static uint32_t fmt_ff2v4l(enum AVPixelFormat pix_fmt, enum AVCodecID codec_id)
Luca Abeni's avatar
Luca Abeni committed
224 225 226
{
    int i;

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

    return 0;
}

239
static enum AVPixelFormat fmt_v4l2ff(uint32_t v4l2_fmt, enum AVCodecID codec_id)
Luca Abeni's avatar
Luca Abeni committed
240 241 242
{
    int i;

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

250
    return AV_PIX_FMT_NONE;
Luca Abeni's avatar
Luca Abeni committed
251 252
}

253
static enum AVCodecID fmt_v4l2codec(uint32_t v4l2_fmt)
254 255 256 257 258 259 260 261 262
{
    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;
        }
    }

263
    return AV_CODEC_ID_NONE;
264 265
}

Luca Barbato's avatar
Luca Barbato committed
266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296
#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)) {
297
        enum AVCodecID codec_id = fmt_v4l2codec(vfd.pixelformat);
298
        enum AVPixelFormat pix_fmt = fmt_v4l2ff(vfd.pixelformat, codec_id);
Luca Barbato's avatar
Luca Barbato committed
299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317

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

318
#ifdef V4L2_FMT_FLAG_EMULATED
Luca Barbato's avatar
Luca Barbato committed
319 320 321 322
        if (vfd.flags & V4L2_FMT_FLAG_EMULATED) {
            av_log(ctx, AV_LOG_WARNING, "%s", "Emulated");
            continue;
        }
323
#endif
Luca Barbato's avatar
Luca Barbato committed
324 325 326 327 328 329 330
#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
331
static int mmap_init(AVFormatContext *ctx)
Luca Abeni's avatar
Luca Abeni committed
332 333
{
    int i, res;
334 335 336 337 338 339
    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
340

341
    res = ioctl(s->fd, VIDIOC_REQBUFS, &req);
Luca Abeni's avatar
Luca Abeni committed
342 343
    if (res < 0) {
        if (errno == EINVAL) {
Luca Abeni's avatar
Luca Abeni committed
344
            av_log(ctx, AV_LOG_ERROR, "Device does not support mmap\n");
Luca Abeni's avatar
Luca Abeni committed
345
        } else {
Luca Abeni's avatar
Luca Abeni committed
346
            av_log(ctx, AV_LOG_ERROR, "ioctl(VIDIOC_REQBUFS)\n");
Luca Abeni's avatar
Luca Abeni committed
347 348
        }

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

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

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

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

369
        return AVERROR(ENOMEM);
Luca Abeni's avatar
Luca Abeni committed
370 371 372
    }

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

379
        res = ioctl(s->fd, VIDIOC_QUERYBUF, &buf);
Luca Abeni's avatar
Luca Abeni committed
380
        if (res < 0) {
Luca Abeni's avatar
Luca Abeni committed
381
            av_log(ctx, AV_LOG_ERROR, "ioctl(VIDIOC_QUERYBUF)\n");
Luca Abeni's avatar
Luca Abeni committed
382

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

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

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

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

    return 0;
}

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

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

417 418 419 420 421 422
    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);

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

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

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

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

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

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

469
        return AVERROR_INVALIDDATA;
470 471
    }

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

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

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

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

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

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

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

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

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

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

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

555 556
    streamparm.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;

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

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

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

580
    if (s->standard) {
Luca Abeni's avatar
Luca Abeni committed
581
        av_log(s1, AV_LOG_DEBUG, "The V4L2 driver set standard: %s\n",
582
               s->standard);
Luca Abeni's avatar
Luca Abeni committed
583 584 585 586
        /* 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
587 588
                av_log(s1, AV_LOG_ERROR,
                       "The V4L2 driver ioctl set standard(%s) failed\n",
589
                       s->standard);
590
                return AVERROR(EIO);
Luca Abeni's avatar
Luca Abeni committed
591 592
            }

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

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

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

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

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

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

644 645 646
    return 0;
}

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

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

672 673
    if (desired_format != 0) {
        *codec_id = fmt_v4l2codec(desired_format);
674
        assert(*codec_id != AV_CODEC_ID_NONE);
675 676 677 678 679
    }

    return desired_format;
}

680
static int v4l2_read_header(AVFormatContext *s1)
Luca Abeni's avatar
Luca Abeni committed
681 682 683
{
    struct video_data *s = s1->priv_data;
    AVStream *st;
684
    int res = 0;
Luca Barbato's avatar
Luca Barbato committed
685
    uint32_t desired_format;
686
    enum AVCodecID codec_id;
687
    enum AVPixelFormat pix_fmt = AV_PIX_FMT_NONE;
Luca Abeni's avatar
Luca Abeni committed
688

689
    st = avformat_new_stream(s1, NULL);
690 691
    if (!st)
        return AVERROR(ENOMEM);
Luca Barbato's avatar
Luca Barbato committed
692

Luca Barbato's avatar
Luca Barbato committed
693
    s->fd = device_open(s1);
694 695
    if (s->fd < 0)
        return s->fd;
Luca Barbato's avatar
Luca Barbato committed
696

Luca Barbato's avatar
Luca Barbato committed
697 698
    if (s->list_format) {
        list_formats(s1, s->fd, s->list_format);
699
        return AVERROR_EXIT;
Luca Barbato's avatar
Luca Barbato committed
700 701
    }

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

Luca Barbato's avatar
Luca Barbato committed
704 705 706 707
    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);
708
        return res;
709
    }
Luca Barbato's avatar
Luca Barbato committed
710 711

    if (s->pixel_format) {
712 713 714 715
        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
716 717 718

        pix_fmt = av_get_pix_fmt(s->pixel_format);

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

723
            return AVERROR(EINVAL);
Luca Barbato's avatar
Luca Barbato committed
724
        }
725
    }
Luca Abeni's avatar
Luca Abeni committed
726

727 728 729
    if (!s->width && !s->height) {
        struct v4l2_format fmt;

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

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

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

752
        return AVERROR(EIO);
Luca Abeni's avatar
Luca Abeni committed
753
    }
Luca Barbato's avatar
Luca Barbato committed
754

755
    if ((res = av_image_check_size(s->width, s->height, 0, s1) < 0))
756
        return res;
Luca Barbato's avatar
Luca Barbato committed
757

Luca Abeni's avatar
Luca Abeni committed
758 759
    s->frame_format = desired_format;

760
    if ((res = v4l2_set_parameters(s1) < 0))
761
        return res;
762

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

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

Luca Abeni's avatar
Luca Abeni committed
773 774
    s->top_field_first = first_field(s->fd);

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

784
    return 0;
Luca Abeni's avatar
Luca Abeni committed
785 786 787 788 789
}

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

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

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

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

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

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

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

816 817
#define OFFSET(x) offsetof(struct video_data, x)
#define DEC AV_OPT_FLAG_DECODING_PARAM
818
static const AVOption options[] = {
819
    { "standard",     "TV standard, used only by analog frame grabber",            OFFSET(standard),     AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0,       DEC },
820
    { "channel",      "TV channel, used only by frame grabber",                    OFFSET(channel),      AV_OPT_TYPE_INT,    {.i64 = 0 },    0, INT_MAX, DEC },
821
    { "video_size",   "A string describing frame size, such as 640x480 or hd720.", OFFSET(video_size),   AV_OPT_TYPE_STRING, {.str = NULL},  0, 0,       DEC },
822 823
    { "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 },
824
    { "framerate",    "",                                                          OFFSET(framerate),    AV_OPT_TYPE_STRING, {.str = NULL},  0, 0,       DEC },
825
    { "list_formats", "List available formats and exit",                           OFFSET(list_format),  AV_OPT_TYPE_INT,    {.i64 = 0 },  0, INT_MAX, DEC, "list_formats" },