v4l2.c 34.7 KB
Newer Older
Luca Abeni's avatar
Luca Abeni committed
1
/*
2 3
 * Copyright (c) 2000,2001 Fabrice Bellard
 * Copyright (c) 2006 Luca Abeni
Luca Abeni's avatar
Luca Abeni committed
4
 *
5 6 7
 * This file is part of FFmpeg.
 *
 * FFmpeg is free software; you can redistribute it and/or
Luca Abeni's avatar
Luca Abeni committed
8 9
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
10
 * version 2.1 of the License, or (at your option) any later version.
Luca Abeni's avatar
Luca Abeni committed
11
 *
12
 * FFmpeg is distributed in the hope that it will be useful,
Luca Abeni's avatar
Luca Abeni committed
13 14 15 16 17
 * 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
18
 * License along with FFmpeg; if not, write to the Free Software
Luca Abeni's avatar
Luca Abeni committed
19 20
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 */
21

22 23 24 25 26
/**
 * @file
 * Video4Linux2 grab interface
 *
 * Part of this file is based on the V4L2 video capture example
27
 * (http://linuxtv.org/downloads/v4l-dvb-apis/capture-example.html)
28 29
 *
 * Thanks to Michael Niedermayer for providing the mapping between
30
 * V4L2_PIX_FMT_* and AV_PIX_FMT_*
31 32
 */

33
#include "v4l2-common.h"
Luca Abeni's avatar
Luca Abeni committed
34

35 36 37 38
#if CONFIG_LIBV4L2
#include <libv4l2.h>
#endif

Luca Abeni's avatar
Luca Abeni committed
39 40
static const int desired_video_buffers = 256;

41 42 43
#define V4L_ALLFORMATS  3
#define V4L_RAWFORMATS  1
#define V4L_COMPFORMATS 2
Luca Abeni's avatar
Luca Abeni committed
44

45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66
/**
 * Return timestamps to the user exactly as returned by the kernel
 */
#define V4L_TS_DEFAULT  0
/**
 * Autodetect the kind of timestamps returned by the kernel and convert to
 * absolute (wall clock) timestamps.
 */
#define V4L_TS_ABS      1
/**
 * Assume kernel timestamps are from the monotonic clock and convert to
 * absolute timestamps.
 */
#define V4L_TS_MONO2ABS 2

/**
 * Once the kind of timestamps returned by the kernel have been detected,
 * the value of the timefilter (NULL or not) determines whether a conversion
 * takes place.
 */
#define V4L_TS_CONVERT_READY V4L_TS_DEFAULT

Luca Abeni's avatar
Luca Abeni committed
67
struct video_data {
68
    AVClass *class;
Luca Abeni's avatar
Luca Abeni committed
69
    int fd;
70
    int pixelformat; /* V4L2_PIX_FMT_* */
Luca Abeni's avatar
Luca Abeni committed
71 72
    int width, height;
    int frame_size;
73
    int interlaced;
Luca Abeni's avatar
Luca Abeni committed
74
    int top_field_first;
75 76 77
    int ts_mode;
    TimeFilter *timefilter;
    int64_t last_time_m;
Luca Abeni's avatar
Luca Abeni committed
78 79

    int buffers;
80
    volatile int buffers_queued;
Luca Abeni's avatar
Luca Abeni committed
81 82
    void **buf_start;
    unsigned int *buf_len;
83
    char *standard;
84
    v4l2_std_id std_id;
85
    int channel;
86
    char *pixel_format; /**< Set by a private option. */
87
    int list_format;    /**< Set by a private option. */
88
    int list_standard;  /**< Set by a private option. */
89
    char *framerate;    /**< Set by a private option. */
90 91 92 93 94 95 96 97 98

    int use_libv4l2;
    int (*open_f)(const char *file, int oflag, ...);
    int (*close_f)(int fd);
    int (*dup_f)(int fd);
    int (*ioctl_f)(int fd, unsigned long int request, ...);
    ssize_t (*read_f)(int fd, void *buffer, size_t n);
    void *(*mmap_f)(void *start, size_t length, int prot, int flags, int fd, int64_t offset);
    int (*munmap_f)(void *_start, size_t length);
Luca Abeni's avatar
Luca Abeni committed
99 100
};

101
struct buff_data {
102
    struct video_data *s;
103 104 105
    int index;
};

106
static int device_open(AVFormatContext *ctx)
Luca Abeni's avatar
Luca Abeni committed
107
{
108
    struct video_data *s = ctx->priv_data;
Luca Abeni's avatar
Luca Abeni committed
109 110
    struct v4l2_capability cap;
    int fd;
111
    int err;
112
    int flags = O_RDWR;
Luca Abeni's avatar
Luca Abeni committed
113

114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142
#define SET_WRAPPERS(prefix) do {       \
    s->open_f   = prefix ## open;       \
    s->close_f  = prefix ## close;      \
    s->dup_f    = prefix ## dup;        \
    s->ioctl_f  = prefix ## ioctl;      \
    s->read_f   = prefix ## read;       \
    s->mmap_f   = prefix ## mmap;       \
    s->munmap_f = prefix ## munmap;     \
} while (0)

    if (s->use_libv4l2) {
#if CONFIG_LIBV4L2
        SET_WRAPPERS(v4l2_);
#else
        av_log(ctx, AV_LOG_ERROR, "libavdevice is not build with libv4l2 support.\n");
        return AVERROR(EINVAL);
#endif
    } else {
        SET_WRAPPERS();
    }

#define v4l2_open   s->open_f
#define v4l2_close  s->close_f
#define v4l2_dup    s->dup_f
#define v4l2_ioctl  s->ioctl_f
#define v4l2_read   s->read_f
#define v4l2_mmap   s->mmap_f
#define v4l2_munmap s->munmap_f

143 144 145
    if (ctx->flags & AVFMT_FLAG_NONBLOCK) {
        flags |= O_NONBLOCK;
    }
Luca Barbato's avatar
Luca Barbato committed
146

147
    fd = v4l2_open(ctx->filename, flags, 0);
Luca Abeni's avatar
Luca Abeni committed
148
    if (fd < 0) {
Tristan Matthews's avatar
Tristan Matthews committed
149
        err = AVERROR(errno);
150
        av_log(ctx, AV_LOG_ERROR, "Cannot open video device %s: %s\n",
151
               ctx->filename, av_err2str(err));
Tristan Matthews's avatar
Tristan Matthews committed
152
        return err;
Luca Abeni's avatar
Luca Abeni committed
153 154
    }

155
    if (v4l2_ioctl(fd, VIDIOC_QUERYCAP, &cap) < 0) {
156
        err = AVERROR(errno);
157
        av_log(ctx, AV_LOG_ERROR, "ioctl(VIDIOC_QUERYCAP): %s\n",
158
               av_err2str(err));
159
        goto fail;
Luca Abeni's avatar
Luca Abeni committed
160
    }
Luca Barbato's avatar
Luca Barbato committed
161

162
    av_log(ctx, AV_LOG_VERBOSE, "fd:%d capabilities:%x\n",
163 164 165 166
           fd, cap.capabilities);

    if (!(cap.capabilities & V4L2_CAP_VIDEO_CAPTURE)) {
        av_log(ctx, AV_LOG_ERROR, "Not a video capture device.\n");
167
        err = AVERROR(ENODEV);
168
        goto fail;
Luca Abeni's avatar
Luca Abeni committed
169
    }
Luca Barbato's avatar
Luca Barbato committed
170

171 172 173
    if (!(cap.capabilities & V4L2_CAP_STREAMING)) {
        av_log(ctx, AV_LOG_ERROR,
               "The device does not support the streaming I/O method.\n");
174
        err = AVERROR(ENOSYS);
175
        goto fail;
Luca Abeni's avatar
Luca Abeni committed
176 177 178
    }

    return fd;
179 180

fail:
181
    v4l2_close(fd);
182
    return err;
Luca Abeni's avatar
Luca Abeni committed
183 184
}

Luca Barbato's avatar
Luca Barbato committed
185
static int device_init(AVFormatContext *ctx, int *width, int *height,
186
                       uint32_t pixelformat)
Luca Abeni's avatar
Luca Abeni committed
187
{
188
    struct video_data *s = ctx->priv_data;
189
    struct v4l2_format fmt = { .type = V4L2_BUF_TYPE_VIDEO_CAPTURE };
190
    int res = 0;
Luca Abeni's avatar
Luca Abeni committed
191

192 193 194 195
    fmt.fmt.pix.width = *width;
    fmt.fmt.pix.height = *height;
    fmt.fmt.pix.pixelformat = pixelformat;
    fmt.fmt.pix.field = V4L2_FIELD_ANY;
Luca Barbato's avatar
Luca Barbato committed
196

197 198
    /* Some drivers will fail and return EINVAL when the pixelformat
       is not supported (even if type field is valid and supported) */
199
    if (v4l2_ioctl(s->fd, VIDIOC_S_FMT, &fmt) < 0)
200
        res = AVERROR(errno);
Luca Barbato's avatar
Luca Barbato committed
201

202
    if ((*width != fmt.fmt.pix.width) || (*height != fmt.fmt.pix.height)) {
Luca Barbato's avatar
Luca Barbato committed
203 204 205
        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);
206 207 208 209
        *width = fmt.fmt.pix.width;
        *height = fmt.fmt.pix.height;
    }

210
    if (pixelformat != fmt.fmt.pix.pixelformat) {
Luca Barbato's avatar
Luca Barbato committed
211 212 213
        av_log(ctx, AV_LOG_DEBUG,
               "The V4L2 driver changed the pixel format "
               "from 0x%08X to 0x%08X\n",
214
               pixelformat, fmt.fmt.pix.pixelformat);
215
        res = AVERROR(EINVAL);
216 217
    }

218
    if (fmt.fmt.pix.field == V4L2_FIELD_INTERLACED) {
219 220
        av_log(ctx, AV_LOG_DEBUG,
               "The V4L2 driver is using the interlaced mode\n");
221 222 223
        s->interlaced = 1;
    }

224
    return res;
Luca Abeni's avatar
Luca Abeni committed
225 226
}

227
static int first_field(const struct video_data *s)
Luca Abeni's avatar
Luca Abeni committed
228 229 230 231
{
    int res;
    v4l2_std_id std;

232 233
    res = v4l2_ioctl(s->fd, VIDIOC_G_STD, &std);
    if (res < 0)
Luca Abeni's avatar
Luca Abeni committed
234
        return 0;
235
    if (std & V4L2_STD_NTSC)
Luca Abeni's avatar
Luca Abeni committed
236 237 238 239 240
        return 0;

    return 1;
}

241
#if HAVE_STRUCT_V4L2_FRMIVALENUM_DISCRETE
242
static void list_framesizes(AVFormatContext *ctx, uint32_t pixelformat)
243
{
244
    const struct video_data *s = ctx->priv_data;
245 246
    struct v4l2_frmsizeenum vfse = { .pixel_format = pixelformat };

247
    while(!v4l2_ioctl(s->fd, VIDIOC_ENUM_FRAMESIZES, &vfse)) {
248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267
        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

268
static void list_formats(AVFormatContext *ctx, int type)
269
{
270
    const struct video_data *s = ctx->priv_data;
271 272
    struct v4l2_fmtdesc vfd = { .type = V4L2_BUF_TYPE_VIDEO_CAPTURE };

273
    while(!v4l2_ioctl(s->fd, VIDIOC_ENUM_FMT, &vfd)) {
274 275
        enum AVCodecID codec_id = ff_fmt_v4l2codec(vfd.pixelformat);
        enum AVPixelFormat pix_fmt = ff_fmt_v4l2ff(vfd.pixelformat, codec_id);
276 277 278 279 280 281

        vfd.index++;

        if (!(vfd.flags & V4L2_FMT_FLAG_COMPRESSED) &&
            type & V4L_RAWFORMATS) {
            const char *fmt_name = av_get_pix_fmt_name(pix_fmt);
282
            av_log(ctx, AV_LOG_INFO, "Raw       : %9s : %20s :",
283 284 285 286
                   fmt_name ? fmt_name : "Unsupported",
                   vfd.description);
        } else if (vfd.flags & V4L2_FMT_FLAG_COMPRESSED &&
                   type & V4L_COMPFORMATS) {
287
            AVCodec *codec = avcodec_find_decoder(codec_id);
288
            av_log(ctx, AV_LOG_INFO, "Compressed: %9s : %20s :",
289 290 291 292 293 294
                   codec ? codec->name : "Unsupported",
                   vfd.description);
        } else {
            continue;
        }

295
#ifdef V4L2_FMT_FLAG_EMULATED
296 297
        if (vfd.flags & V4L2_FMT_FLAG_EMULATED)
            av_log(ctx, AV_LOG_INFO, " Emulated :");
298
#endif
299
#if HAVE_STRUCT_V4L2_FRMIVALENUM_DISCRETE
300
        list_framesizes(ctx, vfd.pixelformat);
301 302 303 304 305
#endif
        av_log(ctx, AV_LOG_INFO, "\n");
    }
}

306 307 308 309 310 311 312 313 314 315
static void list_standards(AVFormatContext *ctx)
{
    int ret;
    struct video_data *s = ctx->priv_data;
    struct v4l2_standard standard;

    if (s->std_id == 0)
        return;

    for (standard.index = 0; ; standard.index++) {
316 317 318
        if (v4l2_ioctl(s->fd, VIDIOC_ENUMSTD, &standard) < 0) {
            ret = AVERROR(errno);
            if (ret == AVERROR(EINVAL)) {
319
                break;
320 321
            } else {
                av_log(ctx, AV_LOG_ERROR, "ioctl(VIDIOC_ENUMSTD): %s\n", av_err2str(ret));
322 323 324
                return;
            }
        }
325 326
        av_log(ctx, AV_LOG_INFO, "%2d, %16"PRIx64", %s\n",
               standard.index, (uint64_t)standard.id, standard.name);
327 328 329
    }
}

330
static int mmap_init(AVFormatContext *ctx)
Luca Abeni's avatar
Luca Abeni committed
331 332
{
    int i, res;
333 334 335 336 337 338
    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
339

340 341 342 343
    if (v4l2_ioctl(s->fd, VIDIOC_REQBUFS, &req) < 0) {
        res = AVERROR(errno);
        av_log(ctx, AV_LOG_ERROR, "ioctl(VIDIOC_REQBUFS): %s\n", av_err2str(res));
        return res;
Luca Abeni's avatar
Luca Abeni committed
344 345 346
    }

    if (req.count < 2) {
347
        av_log(ctx, AV_LOG_ERROR, "Insufficient buffer memory\n");
348
        return AVERROR(ENOMEM);
Luca Abeni's avatar
Luca Abeni committed
349 350
    }
    s->buffers = req.count;
351
    s->buf_start = av_malloc_array(s->buffers, sizeof(void *));
352
    if (!s->buf_start) {
353
        av_log(ctx, AV_LOG_ERROR, "Cannot allocate buffer pointers\n");
354
        return AVERROR(ENOMEM);
Luca Abeni's avatar
Luca Abeni committed
355
    }
356
    s->buf_len = av_malloc_array(s->buffers, sizeof(unsigned int));
357
    if (!s->buf_len) {
358
        av_log(ctx, AV_LOG_ERROR, "Cannot allocate buffer sizes\n");
Luca Abeni's avatar
Luca Abeni committed
359
        av_free(s->buf_start);
360
        return AVERROR(ENOMEM);
Luca Abeni's avatar
Luca Abeni committed
361 362 363
    }

    for (i = 0; i < req.count; i++) {
364 365 366 367 368
        struct v4l2_buffer buf = {
            .type   = V4L2_BUF_TYPE_VIDEO_CAPTURE,
            .index  = i,
            .memory = V4L2_MEMORY_MMAP
        };
369 370 371 372
        if (v4l2_ioctl(s->fd, VIDIOC_QUERYBUF, &buf) < 0) {
            res = AVERROR(errno);
            av_log(ctx, AV_LOG_ERROR, "ioctl(VIDIOC_QUERYBUF): %s\n", av_err2str(res));
            return res;
Luca Abeni's avatar
Luca Abeni committed
373 374 375
        }

        s->buf_len[i] = buf.length;
376
        if (s->frame_size > 0 && s->buf_len[i] < s->frame_size) {
Luca Barbato's avatar
Luca Barbato committed
377
            av_log(ctx, AV_LOG_ERROR,
378
                   "buf_len[%d] = %d < expected frame size %d\n",
Luca Barbato's avatar
Luca Barbato committed
379
                   i, s->buf_len[i], s->frame_size);
380
            return AVERROR(ENOMEM);
Luca Abeni's avatar
Luca Abeni committed
381
        }
382
        s->buf_start[i] = v4l2_mmap(NULL, buf.length,
Luca Barbato's avatar
Luca Barbato committed
383 384 385
                               PROT_READ | PROT_WRITE, MAP_SHARED,
                               s->fd, buf.m.offset);

Luca Abeni's avatar
Luca Abeni committed
386
        if (s->buf_start[i] == MAP_FAILED) {
387 388 389
            res = AVERROR(errno);
            av_log(ctx, AV_LOG_ERROR, "mmap: %s\n", av_err2str(res));
            return res;
Luca Abeni's avatar
Luca Abeni committed
390 391 392 393 394 395
        }
    }

    return 0;
}

396 397 398 399 400 401 402
#if FF_API_DESTRUCT_PACKET
static void dummy_release_buffer(AVPacket *pkt)
{
    av_assert0(0);
}
#endif

403 404 405 406 407 408 409 410 411 412 413 414 415 416
static int enqueue_buffer(struct video_data *s, struct v4l2_buffer *buf)
{
    int res = 0;

    if (v4l2_ioctl(s->fd, VIDIOC_QBUF, buf) < 0) {
        res = AVERROR(errno);
        av_log(NULL, AV_LOG_ERROR, "ioctl(VIDIOC_QBUF): %s\n", av_err2str(res));
    } else {
        avpriv_atomic_int_add_and_fetch(&s->buffers_queued, 1);
    }

    return res;
}

417
static void mmap_release_buffer(void *opaque, uint8_t *data)
418
{
419
    struct v4l2_buffer buf = { 0 };
420 421
    struct buff_data *buf_descriptor = opaque;
    struct video_data *s = buf_descriptor->s;
422

423 424 425 426 427
    buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    buf.memory = V4L2_MEMORY_MMAP;
    buf.index = buf_descriptor->index;
    av_free(buf_descriptor);

428
    enqueue_buffer(s, &buf);
429 430
}

431 432 433
#if HAVE_CLOCK_GETTIME && defined(CLOCK_MONOTONIC)
static int64_t av_gettime_monotonic(void)
{
434
    return av_gettime_relative();
435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450
}
#endif

static int init_convert_timestamp(AVFormatContext *ctx, int64_t ts)
{
    struct video_data *s = ctx->priv_data;
    int64_t now;

    now = av_gettime();
    if (s->ts_mode == V4L_TS_ABS &&
        ts <= now + 1 * AV_TIME_BASE && ts >= now - 10 * AV_TIME_BASE) {
        av_log(ctx, AV_LOG_INFO, "Detected absolute timestamps\n");
        s->ts_mode = V4L_TS_CONVERT_READY;
        return 0;
    }
#if HAVE_CLOCK_GETTIME && defined(CLOCK_MONOTONIC)
451 452 453 454 455 456 457 458 459 460 461 462 463 464
    if (ctx->streams[0]->avg_frame_rate.num) {
        now = av_gettime_monotonic();
        if (s->ts_mode == V4L_TS_MONO2ABS ||
            (ts <= now + 1 * AV_TIME_BASE && ts >= now - 10 * AV_TIME_BASE)) {
            AVRational tb = {AV_TIME_BASE, 1};
            int64_t period = av_rescale_q(1, tb, ctx->streams[0]->avg_frame_rate);
            av_log(ctx, AV_LOG_INFO, "Detected monotonic timestamps, converting\n");
            /* microseconds instead of seconds, MHz instead of Hz */
            s->timefilter = ff_timefilter_new(1, period, 1.0E-6);
            if (!s->timefilter)
                return AVERROR(ENOMEM);
            s->ts_mode = V4L_TS_CONVERT_READY;
            return 0;
        }
465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491
    }
#endif
    av_log(ctx, AV_LOG_ERROR, "Unknown timestamps\n");
    return AVERROR(EIO);
}

static int convert_timestamp(AVFormatContext *ctx, int64_t *ts)
{
    struct video_data *s = ctx->priv_data;

    if (s->ts_mode) {
        int r = init_convert_timestamp(ctx, *ts);
        if (r < 0)
            return r;
    }
#if HAVE_CLOCK_GETTIME && defined(CLOCK_MONOTONIC)
    if (s->timefilter) {
        int64_t nowa = av_gettime();
        int64_t nowm = av_gettime_monotonic();
        ff_timefilter_update(s->timefilter, nowa, nowm - s->last_time_m);
        s->last_time_m = nowm;
        *ts = ff_timefilter_eval(s->timefilter, *ts - nowm);
    }
#endif
    return 0;
}

492
static int mmap_read_frame(AVFormatContext *ctx, AVPacket *pkt)
Luca Abeni's avatar
Luca Abeni committed
493
{
494
    struct video_data *s = ctx->priv_data;
495 496 497 498
    struct v4l2_buffer buf = {
        .type   = V4L2_BUF_TYPE_VIDEO_CAPTURE,
        .memory = V4L2_MEMORY_MMAP
    };
Luca Abeni's avatar
Luca Abeni committed
499 500 501
    int res;

    /* FIXME: Some special treatment might be needed in case of loss of signal... */
502
    while ((res = v4l2_ioctl(s->fd, VIDIOC_DQBUF, &buf)) < 0 && (errno == EINTR));
Luca Abeni's avatar
Luca Abeni committed
503
    if (res < 0) {
504 505 506 507
        if (errno == EAGAIN) {
            pkt->size = 0;
            return AVERROR(EAGAIN);
        }
508
        res = AVERROR(errno);
Luca Barbato's avatar
Luca Barbato committed
509
        av_log(ctx, AV_LOG_ERROR, "ioctl(VIDIOC_DQBUF): %s\n",
510
               av_err2str(res));
511
        return res;
Luca Abeni's avatar
Luca Abeni committed
512
    }
513 514 515 516 517

    if (buf.index >= s->buffers) {
        av_log(ctx, AV_LOG_ERROR, "Invalid buffer index received.\n");
        return AVERROR(EINVAL);
    }
518 519 520
    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);
Stephan Hilb's avatar
Stephan Hilb committed
521 522 523 524 525 526 527

    /* CPIA is a compressed format and we don't know the exact number of bytes
     * used by a frame, so set it here as the driver announces it.
     */
    if (ctx->video_codec_id == AV_CODEC_ID_CPIA)
        s->frame_size = buf.bytesused;

528
    if (s->frame_size > 0 && buf.bytesused != s->frame_size) {
Luca Barbato's avatar
Luca Barbato committed
529 530 531
        av_log(ctx, AV_LOG_ERROR,
               "The v4l2 frame is %d bytes, but %d bytes are expected\n",
               buf.bytesused, s->frame_size);
532
        enqueue_buffer(s, &buf);
533
        return AVERROR_INVALIDDATA;
534 535
    }

Luca Abeni's avatar
Luca Abeni committed
536
    /* Image is at s->buff_start[buf.index] */
537
    if (avpriv_atomic_int_get(&s->buffers_queued) == FFMAX(s->buffers / 8, 1)) {
Diego Biurrun's avatar
Diego Biurrun committed
538
        /* when we start getting low on queued buffers, fall back on copying data */
539 540 541
        res = av_new_packet(pkt, buf.bytesused);
        if (res < 0) {
            av_log(ctx, AV_LOG_ERROR, "Error allocating a packet.\n");
542
            enqueue_buffer(s, &buf);
543 544 545
            return res;
        }
        memcpy(pkt->data, s->buf_start[buf.index], buf.bytesused);
546

547 548
        res = enqueue_buffer(s, &buf);
        if (res) {
549
            av_free_packet(pkt);
550
            return res;
551
        }
552
    } else {
553
        struct buff_data *buf_descriptor;
Luca Abeni's avatar
Luca Abeni committed
554

555 556 557
        pkt->data     = s->buf_start[buf.index];
        pkt->size     = buf.bytesused;
#if FF_API_DESTRUCT_PACKET
558
FF_DISABLE_DEPRECATION_WARNINGS
559
        pkt->destruct = dummy_release_buffer;
560
FF_ENABLE_DEPRECATION_WARNINGS
561 562 563
#endif

        buf_descriptor = av_malloc(sizeof(struct buff_data));
564
        if (!buf_descriptor) {
565 566 567 568
            /* 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");
569
            enqueue_buffer(s, &buf);
570 571 572

            return AVERROR(ENOMEM);
        }
573
        buf_descriptor->index = buf.index;
574 575 576 577 578
        buf_descriptor->s     = s;

        pkt->buf = av_buffer_create(pkt->data, pkt->size, mmap_release_buffer,
                                    buf_descriptor, 0);
        if (!pkt->buf) {
579
            av_log(ctx, AV_LOG_ERROR, "Failed to create a buffer\n");
580
            enqueue_buffer(s, &buf);
581 582 583
            av_freep(&buf_descriptor);
            return AVERROR(ENOMEM);
        }
584 585
    }
    pkt->pts = buf.timestamp.tv_sec * INT64_C(1000000) + buf.timestamp.tv_usec;
586
    convert_timestamp(ctx, &pkt->pts);
Luca Abeni's avatar
Luca Abeni committed
587 588 589 590

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

591
static int mmap_start(AVFormatContext *ctx)
Luca Abeni's avatar
Luca Abeni committed
592
{
593
    struct video_data *s = ctx->priv_data;
Luca Abeni's avatar
Luca Abeni committed
594 595 596 597
    enum v4l2_buf_type type;
    int i, res;

    for (i = 0; i < s->buffers; i++) {
598 599 600 601 602
        struct v4l2_buffer buf = {
            .type   = V4L2_BUF_TYPE_VIDEO_CAPTURE,
            .index  = i,
            .memory = V4L2_MEMORY_MMAP
        };
Luca Abeni's avatar
Luca Abeni committed
603

604 605
        if (v4l2_ioctl(s->fd, VIDIOC_QBUF, &buf) < 0) {
            res = AVERROR(errno);
Luca Barbato's avatar
Luca Barbato committed
606
            av_log(ctx, AV_LOG_ERROR, "ioctl(VIDIOC_QBUF): %s\n",
607
                   av_err2str(res));
608
            return res;
Luca Abeni's avatar
Luca Abeni committed
609 610
        }
    }
611
    s->buffers_queued = s->buffers;
Luca Abeni's avatar
Luca Abeni committed
612 613

    type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
614 615
    if (v4l2_ioctl(s->fd, VIDIOC_STREAMON, &type) < 0) {
        res = AVERROR(errno);
Luca Barbato's avatar
Luca Barbato committed
616
        av_log(ctx, AV_LOG_ERROR, "ioctl(VIDIOC_STREAMON): %s\n",
617
               av_err2str(res));
618
        return res;
Luca Abeni's avatar
Luca Abeni committed
619 620 621 622 623 624 625 626 627 628 629 630 631 632
    }

    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...
     */
633
    v4l2_ioctl(s->fd, VIDIOC_STREAMOFF, &type);
Luca Abeni's avatar
Luca Abeni committed
634
    for (i = 0; i < s->buffers; i++) {
635
        v4l2_munmap(s->buf_start[i], s->buf_len[i]);
Luca Abeni's avatar
Luca Abeni committed
636 637 638 639 640
    }
    av_free(s->buf_start);
    av_free(s->buf_len);
}

641
static int v4l2_set_parameters(AVFormatContext *ctx)
642
{
643
    struct video_data *s = ctx->priv_data;
644
    struct v4l2_standard standard = { 0 };
645
    struct v4l2_streamparm streamparm = { 0 };
646
    struct v4l2_fract *tpf;
647
    AVRational framerate_q = { 0 };
648
    int i, ret;
649

Luca Barbato's avatar
Luca Barbato committed
650 651
    if (s->framerate &&
        (ret = av_parse_video_rate(&framerate_q, s->framerate)) < 0) {
652
        av_log(ctx, AV_LOG_ERROR, "Could not parse framerate '%s'.\n",
Luca Barbato's avatar
Luca Barbato committed
653
               s->framerate);
654 655
        return ret;
    }
656

657
    if (s->standard) {
658
        if (s->std_id) {
659
            ret = 0;
660
            av_log(ctx, AV_LOG_DEBUG, "Setting standard: %s\n", s->standard);
661 662 663
            /* set tv standard */
            for (i = 0; ; i++) {
                standard.index = i;
664
                if (v4l2_ioctl(s->fd, VIDIOC_ENUMSTD, &standard) < 0) {
665
                    ret = AVERROR(errno);
666 667 668
                    break;
                }
                if (!av_strcasecmp(standard.name, s->standard))
669 670 671
                    break;
            }
            if (ret < 0) {
672
                av_log(ctx, AV_LOG_ERROR, "Unknown or unsupported standard '%s'\n", s->standard);
673
                return ret;
674 675 676
            }

            if (v4l2_ioctl(s->fd, VIDIOC_S_STD, &standard.id) < 0) {
677
                ret = AVERROR(errno);
678
                av_log(ctx, AV_LOG_ERROR, "ioctl(VIDIOC_S_STD): %s\n", av_err2str(ret));
679
                return ret;
680 681
            }
        } else {
682
            av_log(ctx, AV_LOG_WARNING,
683 684 685 686 687 688 689 690
                   "This device does not support any standard\n");
        }
    }

    /* get standard */
    if (v4l2_ioctl(s->fd, VIDIOC_G_STD, &s->std_id) == 0) {
        tpf = &standard.frameperiod;
        for (i = 0; ; i++) {
691
            standard.index = i;
692 693
            if (v4l2_ioctl(s->fd, VIDIOC_ENUMSTD, &standard) < 0) {
                ret = AVERROR(errno);
694 695 696 697 698
                if (ret == AVERROR(EINVAL)
#ifdef ENODATA
                    || ret == AVERROR(ENODATA)
#endif
                ) {
699 700 701
                    tpf = &streamparm.parm.capture.timeperframe;
                    break;
                }
702
                av_log(ctx, AV_LOG_ERROR, "ioctl(VIDIOC_ENUMSTD): %s\n", av_err2str(ret));
703
                return ret;
704 705
            }
            if (standard.id == s->std_id) {
706
                av_log(ctx, AV_LOG_DEBUG,
707
                       "Current standard: %s, id: %"PRIx64", frameperiod: %d/%d\n",
708
                       standard.name, (uint64_t)standard.id, tpf->numerator, tpf->denominator);
709
                break;
710
            }
711
        }
712 713 714
    } else {
        tpf = &streamparm.parm.capture.timeperframe;
    }
715

716 717
    streamparm.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    if (v4l2_ioctl(s->fd, VIDIOC_G_PARM, &streamparm) < 0) {
718
        ret = AVERROR(errno);
719
        av_log(ctx, AV_LOG_ERROR, "ioctl(VIDIOC_G_PARM): %s\n", av_err2str(ret));
720
        return ret;
721
    }
722

723
    if (framerate_q.num && framerate_q.den) {
724 725 726
        if (streamparm.parm.capture.capability & V4L2_CAP_TIMEPERFRAME) {
            tpf = &streamparm.parm.capture.timeperframe;

727
            av_log(ctx, AV_LOG_DEBUG, "Setting time per frame to %d/%d\n",
728
                   framerate_q.den, framerate_q.num);
729 730
            tpf->numerator   = framerate_q.den;
            tpf->denominator = framerate_q.num;
731

732
            if (v4l2_ioctl(s->fd, VIDIOC_S_PARM, &streamparm) < 0) {
733
                ret = AVERROR(errno);
734 735
                av_log(ctx, AV_LOG_ERROR, "ioctl(VIDIOC_S_PARM): %s\n",
                       av_err2str(ret));
736
                return ret;
737 738 739 740
            }

            if (framerate_q.num != tpf->denominator ||
                framerate_q.den != tpf->numerator) {
741
                av_log(ctx, AV_LOG_INFO,
742 743 744 745 746 747
                       "The driver changed the time per frame from "
                       "%d/%d to %d/%d\n",
                       framerate_q.den, framerate_q.num,
                       tpf->numerator, tpf->denominator);
            }
        } else {
748
            av_log(ctx, AV_LOG_WARNING,
749
                   "The driver does not allow to change time per frame\n");
750
        }
751
    }
752
    if (tpf->denominator > 0 && tpf->numerator > 0) {
753 754 755
        ctx->streams[0]->avg_frame_rate.num = tpf->denominator;
        ctx->streams[0]->avg_frame_rate.den = tpf->numerator;
        ctx->streams[0]->r_frame_rate = ctx->streams[0]->avg_frame_rate;
756
    } else
757
        av_log(ctx, AV_LOG_WARNING, "Time per frame unknown\n");
758

759 760 761
    return 0;
}

762
static int device_try_init(AVFormatContext *ctx,
763 764 765 766 767
                           enum AVPixelFormat pix_fmt,
                           int *width,
                           int *height,
                           uint32_t *desired_format,
                           enum AVCodecID *codec_id)
768
{
769
    int ret, i;
770

771
    *desired_format = ff_fmt_ff2v4l(pix_fmt, ctx->video_codec_id);
772

773
    if (*desired_format) {
774
        ret = device_init(ctx, width, height, *desired_format);
775 776 777 778 779 780 781 782
        if (ret < 0) {
            *desired_format = 0;
            if (ret != AVERROR(EINVAL))
                return ret;
        }
    }

    if (!*desired_format) {
783
        for (i = 0; ff_fmt_conversion_table[i].codec_id != AV_CODEC_ID_NONE; i++) {
784
            if (ctx->video_codec_id == AV_CODEC_ID_NONE ||
785
                ff_fmt_conversion_table[i].codec_id == ctx->video_codec_id) {
786
                av_log(ctx, AV_LOG_DEBUG, "Trying to set codec:%s pix_fmt:%s\n",
787 788
                       avcodec_get_name(ff_fmt_conversion_table[i].codec_id),
                       (char *)av_x_if_null(av_get_pix_fmt_name(ff_fmt_conversion_table[i].ff_fmt), "none"));
789

790
                *desired_format = ff_fmt_conversion_table[i].v4l2_fmt;
791
                ret = device_init(ctx, width, height, *desired_format);
792
                if (ret >= 0)
793
                    break;
794 795 796
                else if (ret != AVERROR(EINVAL))
                    return ret;
                *desired_format = 0;
797 798
            }
        }
Luca Barbato's avatar
Luca Barbato committed
799

800
        if (*desired_format == 0) {
801
            av_log(ctx, AV_LOG_ERROR, "Cannot find a proper format for "
802
                   "codec '%s' (id %d), pixel format '%s' (id %d)\n",
803
                   avcodec_get_name(ctx->video_codec_id), ctx->video_codec_id,
804 805 806
                   (char *)av_x_if_null(av_get_pix_fmt_name(pix_fmt), "none"), pix_fmt);
            ret = AVERROR(EINVAL);
        }
807 808
    }

809
    *codec_id = ff_fmt_v4l2codec(*desired_format);
810 811
    av_assert0(*codec_id != AV_CODEC_ID_NONE);
    return ret;
812 813
}

814 815 816 817 818 819 820
static int v4l2_read_probe(AVProbeData *p)
{
    if (av_strstart(p->filename, "/dev/video", NULL))
        return AVPROBE_SCORE_MAX - 1;
    return 0;
}

821
static int v4l2_read_header(AVFormatContext *ctx)
Luca Abeni's avatar
Luca Abeni committed
822
{
823
    struct video_data *s = ctx->priv_data;
Luca Abeni's avatar
Luca Abeni committed
824
    AVStream *st;
825
    int res = 0;
826
    uint32_t desired_format;
Stephan Hilb's avatar
Stephan Hilb committed
827
    enum AVCodecID codec_id = AV_CODEC_ID_NONE;
828
    enum AVPixelFormat pix_fmt = AV_PIX_FMT_NONE;
829
    struct v4l2_input input = { 0 };
Luca Abeni's avatar
Luca Abeni committed
830

831
    st = avformat_new_stream(ctx, NULL);
832 833
    if (!st)
        return AVERROR(ENOMEM);
Luca Abeni's avatar
Luca Abeni committed
834

835 836 837
#if CONFIG_LIBV4L2
    /* silence libv4l2 logging. if fopen() fails v4l2_log_file will be NULL
       and errors will get sent to stderr */
838 839
    if (s->use_libv4l2)
        v4l2_log_file = fopen("/dev/null", "w");
840 841
#endif

842
    s->fd = device_open(ctx);
843 844
    if (s->fd < 0)
        return s->fd;
845

846 847
    if (s->channel != -1) {
        /* set video input */
848
        av_log(ctx, AV_LOG_DEBUG, "Selecting input_channel: %d\n", s->channel);
849 850
        if (v4l2_ioctl(s->fd, VIDIOC_S_INPUT, &s->channel) < 0) {
            res = AVERROR(errno);
851
            av_log(ctx, AV_LOG_ERROR, "ioctl(VIDIOC_S_INPUT): %s\n", av_err2str(res));
852
            goto fail;
853 854 855 856 857
        }
    } else {
        /* get current video input */
        if (v4l2_ioctl(s->fd, VIDIOC_G_INPUT, &s->channel) < 0) {
            res = AVERROR(errno);
858
            av_log(ctx, AV_LOG_ERROR, "ioctl(VIDIOC_G_INPUT): %s\n", av_err2str(res));
859
            goto fail;
860
        }
861 862
    }

863
    /* enum input */
864 865
    input.index = s->channel;
    if (v4l2_ioctl(s->fd, VIDIOC_ENUMINPUT, &input) < 0) {
866
        res = AVERROR(errno);
867
        av_log(ctx, AV_LOG_ERROR, "ioctl(VIDIOC_ENUMINPUT): %s\n", av_err2str(res));
868
        goto fail;
869 870
    }
    s->std_id = input.std;
871
    av_log(ctx, AV_LOG_DEBUG, "Current input_channel: %d, input_name: %s, input_std: %"PRIx64"\n",
872
           s->channel, input.name, (uint64_t)input.std);
873

874
    if (s->list_format) {
875
        list_formats(ctx, s->list_format);
876 877
        res = AVERROR_EXIT;
        goto fail;
878
    }
Luca Abeni's avatar
Luca Abeni committed
879

880
    if (s->list_standard) {
881
        list_standards(ctx);
882 883
        res = AVERROR_EXIT;
        goto fail;
884 885
    }

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

888
    if (s->pixel_format) {
889 890 891
        AVCodec *codec = avcodec_find_decoder_by_name(s->pixel_format);

        if (codec)
892
            ctx->video_codec_id = codec->id;
893 894 895

        pix_fmt = av_get_pix_fmt(s->pixel_format);

896
        if (pix_fmt == AV_PIX_FMT_NONE && !codec) {
897
            av_log(ctx, AV_LOG_ERROR, "No such input format: %s.\n",
898 899
                   s->pixel_format);

900 901
            res = AVERROR(EINVAL);
            goto fail;
902
        }
903
    }
Luca Abeni's avatar
Luca Abeni committed
904

905
    if (!s->width && !s->height) {
906
        struct v4l2_format fmt = { .type = V4L2_BUF_TYPE_VIDEO_CAPTURE };
907

908
        av_log(ctx, AV_LOG_VERBOSE,
Luca Barbato's avatar
Luca Barbato committed
909
               "Querying the device for the current frame size\n");
910
        if (v4l2_ioctl(s->fd, VIDIOC_G_FMT, &fmt) < 0) {
911
            res = AVERROR(errno);
912 913
            av_log(ctx, AV_LOG_ERROR, "ioctl(VIDIOC_G_FMT): %s\n",
                   av_err2str(res));
914
            goto fail;
915
        }
Luca Barbato's avatar
Luca Barbato committed
916

917 918
        s->width  = fmt.fmt.pix.width;
        s->height = fmt.fmt.pix.height;
919
        av_log(ctx, AV_LOG_VERBOSE,
Luca Barbato's avatar
Luca Barbato committed
920
               "Setting frame size to %dx%d\n", s->width, s->height);
921 922
    }

923
    res = device_try_init(ctx, pix_fmt, &s->width, &s->height, &desired_format, &codec_id);
924 925
    if (res < 0)
        goto fail;
Stephan Hilb's avatar
Stephan Hilb committed
926 927 928 929 930

    /* If no pixel_format was specified, the codec_id was not known up
     * until now. Set video_codec_id in the context, as codec_id will
     * not be available outside this function
     */
931 932
    if (codec_id != AV_CODEC_ID_NONE && ctx->video_codec_id == AV_CODEC_ID_NONE)
        ctx->video_codec_id = codec_id;
Stephan Hilb's avatar
Stephan Hilb committed
933

934
    if ((res = av_image_check_size(s->width, s->height, 0, ctx)) < 0)
935
        goto fail;
Luca Barbato's avatar
Luca Barbato committed
936

937
    s->pixelformat = desired_format;
Luca Abeni's avatar
Luca Abeni committed
938

939 940 941
    if ((res = v4l2_set_parameters(ctx)) < 0)
        goto fail;

942
    st->codec->pix_fmt = ff_fmt_v4l2ff(desired_format, codec_id);
Luca Barbato's avatar
Luca Barbato committed
943 944 945
    s->frame_size =
        avpicture_get_size(st->codec->pix_fmt, s->width, s->height);

946 947
    if ((res = mmap_init(ctx)) ||
        (res = mmap_start(ctx)) < 0)
948
            goto fail;
949

950
    s->top_field_first = first_field(s);
Luca Abeni's avatar
Luca Abeni committed
951

952
    st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
953
    st->codec->codec_id = codec_id;
954
    if (codec_id == AV_CODEC_ID_RAWVIDEO)
955 956
        st->codec->codec_tag =
            avcodec_pix_fmt_to_codec_tag(st->codec->pix_fmt);
957 958 959
    else if (codec_id == AV_CODEC_ID_H264) {
        st->need_parsing = AVSTREAM_PARSE_HEADERS;
    }
960 961
    if (desired_format == V4L2_PIX_FMT_YVU420)
        st->codec->codec_tag = MKTAG('Y', 'V', '1', '2');
962 963
    else if (desired_format == V4L2_PIX_FMT_YVU410)
        st->codec->codec_tag = MKTAG('Y', 'V', 'U', '9');
964 965
    st->codec->width = s->width;
    st->codec->height = s->height;
966 967
    if (st->avg_frame_rate.den)
        st->codec->bit_rate = s->frame_size * av_q2d(st->avg_frame_rate) * 8;
Luca Abeni's avatar
Luca Abeni committed
968

969
    return 0;
970 971 972 973

fail:
    v4l2_close(s->fd);
    return res;
Luca Abeni's avatar
Luca Abeni committed
974 975
}

976
static int v4l2_read_packet(AVFormatContext *ctx, AVPacket *pkt)
Luca Abeni's avatar
Luca Abeni committed
977
{
978 979
    struct video_data *s = ctx->priv_data;
    AVFrame *frame = ctx->streams[0]->codec->coded_frame;
Luca Abeni's avatar
Luca Abeni committed
980 981
    int res;

982
    av_init_packet(pkt);
983
    if ((res = mmap_read_frame(ctx, pkt)) < 0) {
984
        return res;
Luca Abeni's avatar
Luca Abeni committed
985 986
    }

Luca Barbato's avatar
Luca Barbato committed
987 988 989
    if (frame && s->interlaced) {
        frame->interlaced_frame = 1;
        frame->top_field_first = s->top_field_first;
Luca Abeni's avatar
Luca Abeni committed
990 991
    }

992
    return pkt->size;
Luca Abeni's avatar
Luca Abeni committed
993 994
}

995
static int v4l2_read_close(AVFormatContext *ctx)
Luca Abeni's avatar
Luca Abeni committed
996
{
997
    struct video_data *s = ctx->priv_data;
Luca Abeni's avatar
Luca Abeni committed
998

999
    if (avpriv_atomic_int_get(&s->buffers_queued) != s->buffers)
1000
        av_log(ctx, AV_LOG_WARNING, "Some buffers are still owned by the caller on "
1001 1002
               "close.\n");

1003
    mmap_close(s);
Luca Abeni's avatar
Luca Abeni committed
1004

1005
    v4l2_close(s->fd);
Luca Abeni's avatar
Luca Abeni committed
1006 1007 1008
    return 0;
}

1009 1010
#define OFFSET(x) offsetof(struct video_data, x)
#define DEC AV_OPT_FLAG_DECODING_PARAM
1011

1012
static const AVOption options[] = {
1013
    { "standard",     "set TV standard, used only by analog frame grabber",       OFFSET(standard),     AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0,       DEC },
1014
    { "channel",      "set TV channel, used only by frame grabber",               OFFSET(channel),      AV_OPT_TYPE_INT,    {.i64 = -1 },  -1, INT_MAX, DEC },
1015 1016 1017 1018 1019 1020 1021 1022 1023 1024
    { "video_size",   "set frame size",                                           OFFSET(width),        AV_OPT_TYPE_IMAGE_SIZE, {.str = NULL},  0, 0,   DEC },
    { "pixel_format", "set preferred pixel format",                               OFFSET(pixel_format), AV_OPT_TYPE_STRING, {.str = NULL},  0, 0,       DEC },
    { "input_format", "set preferred pixel format (for raw video) or codec name", OFFSET(pixel_format), AV_OPT_TYPE_STRING, {.str = NULL},  0, 0,       DEC },
    { "framerate",    "set frame rate",                                           OFFSET(framerate),    AV_OPT_TYPE_STRING, {.str = NULL},  0, 0,       DEC },

    { "list_formats", "list available formats and exit",                          OFFSET(list_format),  AV_OPT_TYPE_INT,    {.i64 = 0 },  0, INT_MAX, DEC, "list_formats" },
    { "all",          "show all available formats",                               OFFSET(list_format),  AV_OPT_TYPE_CONST,  {.i64 = V4L_ALLFORMATS  },    0, INT_MAX, DEC, "list_formats" },
    { "raw",          "show only non-compressed formats",                         OFFSET(list_format),  AV_OPT_TYPE_CONST,  {.i64 = V4L_RAWFORMATS  },    0, INT_MAX, DEC, "list_formats" },
    { "compressed",   "show only compressed formats",                             OFFSET(list_format),  AV_OPT_TYPE_CONST,  {.i64 = V4L_COMPFORMATS },    0, INT_MAX, DEC, "list_formats" },

1025 1026 1027
    { "list_standards", "list supported standards and exit",                      OFFSET(list_standard), AV_OPT_TYPE_INT,   {.i64 = 0 },  0, 1, DEC, "list_standards" },
    { "all",            "show all supported standards",                           OFFSET(list_standard), AV_OPT_TYPE_CONST, {.i64 = 1 },  0, 0, DEC, "list_standards" },

1028 1029 1030 1031 1032
    { "timestamps",   "set type of timestamps for grabbed frames",                OFFSET(ts_mode),      AV_OPT_TYPE_INT,    {.i64 = 0 }, 0, 2, DEC, "timestamps" },
    { "ts",           "set type of timestamps for grabbed frames",                OFFSET(ts_mode),      AV_OPT_TYPE_INT,    {.i64 = 0 }, 0, 2, DEC, "timestamps" },
    { "default",      "use timestamps from the kernel",                           OFFSET(ts_mode),      AV_OPT_TYPE_CONST,  {.i64 = V4L_TS_DEFAULT  }, 0, 2, DEC, "timestamps" },
    { "abs",          "use absolute timestamps (wall clock)",                     OFFSET(ts_mode),      AV_OPT_TYPE_CONST,  {.i64 = V4L_TS_ABS      }, 0, 2, DEC, "timestamps" },
    { "mono2abs",     "force conversion from monotonic to absolute timestamps",   OFFSET(ts_mode),      AV_OPT_TYPE_CONST,  {.i64 = V4L_TS_MONO2ABS }, 0, 2, DEC, "timestamps" },
1033
    { "use_libv4l2",  "use libv4l2 (v4l-utils) conversion functions",             OFFSET(use_libv4l2),  AV_OPT_TYPE_INT,    {.i64 = 0}, 0, 1, DEC },
1034 1035 1036 1037 1038 1039 1040 1041
    { NULL },
};

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

1045
AVInputFormat ff_v4l2_demuxer = {
1046
    .name           = "video4linux2,v4l2",
1047 1048
    .long_name      = NULL_IF_CONFIG_SMALL("Video4Linux2 device grab"),
    .priv_data_size = sizeof(struct video_data),
1049
    .read_probe     = v4l2_read_probe,
1050 1051 1052 1053 1054
    .read_header    = v4l2_read_header,
    .read_packet    = v4l2_read_packet,
    .read_close     = v4l2_read_close,
    .flags          = AVFMT_NOFILE,
    .priv_class     = &v4l2_class,
Luca Abeni's avatar
Luca Abeni committed
1055
};