v4l2.c 37.2 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"
34
#include <dirent.h>
Luca Abeni's avatar
Luca Abeni committed
35

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

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

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

46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67
/**
 * 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
68
struct video_data {
69
    AVClass *class;
Luca Abeni's avatar
Luca Abeni committed
70
    int fd;
71
    int pixelformat; /* V4L2_PIX_FMT_* */
Luca Abeni's avatar
Luca Abeni committed
72 73
    int width, height;
    int frame_size;
74
    int interlaced;
Luca Abeni's avatar
Luca Abeni committed
75
    int top_field_first;
76 77 78
    int ts_mode;
    TimeFilter *timefilter;
    int64_t last_time_m;
Luca Abeni's avatar
Luca Abeni committed
79 80

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

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

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

107
static int device_open(AVFormatContext *ctx)
Luca Abeni's avatar
Luca Abeni committed
108
{
109
    struct video_data *s = ctx->priv_data;
Luca Abeni's avatar
Luca Abeni committed
110 111
    struct v4l2_capability cap;
    int fd;
112
    int err;
113
    int flags = O_RDWR;
Luca Abeni's avatar
Luca Abeni committed
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 143
#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

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

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

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

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

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

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

    return fd;
180 181

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

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

193 194 195 196
    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
197

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

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

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

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

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

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

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

    return 1;
}

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

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

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

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

        vfd.index++;

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

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

307 308 309 310 311 312 313 314 315 316
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++) {
317 318 319
        if (v4l2_ioctl(s->fd, VIDIOC_ENUMSTD, &standard) < 0) {
            ret = AVERROR(errno);
            if (ret == AVERROR(EINVAL)) {
320
                break;
321 322
            } else {
                av_log(ctx, AV_LOG_ERROR, "ioctl(VIDIOC_ENUMSTD): %s\n", av_err2str(ret));
323 324 325
                return;
            }
        }
326 327
        av_log(ctx, AV_LOG_INFO, "%2d, %16"PRIx64", %s\n",
               standard.index, (uint64_t)standard.id, standard.name);
328 329 330
    }
}

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 342 343 344
    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
345 346 347
    }

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

    for (i = 0; i < req.count; i++) {
365 366 367 368 369
        struct v4l2_buffer buf = {
            .type   = V4L2_BUF_TYPE_VIDEO_CAPTURE,
            .index  = i,
            .memory = V4L2_MEMORY_MMAP
        };
370 371 372 373
        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
374 375 376
        }

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

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

    return 0;
}

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

404 405 406 407 408 409 410 411 412 413 414 415 416 417
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;
}

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

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

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

432 433 434
#if HAVE_CLOCK_GETTIME && defined(CLOCK_MONOTONIC)
static int64_t av_gettime_monotonic(void)
{
435
    return av_gettime_relative();
436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451
}
#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)
452 453 454 455 456 457 458 459 460 461 462 463 464 465
    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;
        }
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 492
    }
#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;
}

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

502 503
    pkt->size = 0;

Luca Abeni's avatar
Luca Abeni committed
504
    /* FIXME: Some special treatment might be needed in case of loss of signal... */
505
    while ((res = v4l2_ioctl(s->fd, VIDIOC_DQBUF, &buf)) < 0 && (errno == EINTR));
Luca Abeni's avatar
Luca Abeni committed
506
    if (res < 0) {
507
        if (errno == EAGAIN)
508
            return AVERROR(EAGAIN);
509

510
        res = AVERROR(errno);
Luca Barbato's avatar
Luca Barbato committed
511
        av_log(ctx, AV_LOG_ERROR, "ioctl(VIDIOC_DQBUF): %s\n",
512
               av_err2str(res));
513
        return res;
Luca Abeni's avatar
Luca Abeni committed
514
    }
515 516 517 518 519

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

524
#ifdef V4L2_BUF_FLAG_ERROR
525 526 527 528 529
    if (buf.flags & V4L2_BUF_FLAG_ERROR) {
        av_log(ctx, AV_LOG_WARNING,
               "Dequeued v4l2 buffer contains corrupted data (%d bytes).\n",
               buf.bytesused);
        buf.bytesused = 0;
530 531 532
    } else
#endif
    {
533 534 535 536
        /* 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;
Stephan Hilb's avatar
Stephan Hilb committed
537

538 539 540 541 542 543 544
        if (s->frame_size > 0 && buf.bytesused != s->frame_size) {
            av_log(ctx, AV_LOG_ERROR,
                   "Dequeued v4l2 buffer contains %d bytes, but %d were expected. Flags: 0x%08X.\n",
                   buf.bytesused, s->frame_size, buf.flags);
            enqueue_buffer(s, &buf);
            return AVERROR_INVALIDDATA;
        }
545 546
    }

Luca Abeni's avatar
Luca Abeni committed
547
    /* Image is at s->buff_start[buf.index] */
548
    if (avpriv_atomic_int_get(&s->buffers_queued) == FFMAX(s->buffers / 8, 1)) {
Diego Biurrun's avatar
Diego Biurrun committed
549
        /* when we start getting low on queued buffers, fall back on copying data */
550 551 552
        res = av_new_packet(pkt, buf.bytesused);
        if (res < 0) {
            av_log(ctx, AV_LOG_ERROR, "Error allocating a packet.\n");
553
            enqueue_buffer(s, &buf);
554 555 556
            return res;
        }
        memcpy(pkt->data, s->buf_start[buf.index], buf.bytesused);
557

558 559
        res = enqueue_buffer(s, &buf);
        if (res) {
560
            av_free_packet(pkt);
561
            return res;
562
        }
563
    } else {
564
        struct buff_data *buf_descriptor;
Luca Abeni's avatar
Luca Abeni committed
565

566 567 568
        pkt->data     = s->buf_start[buf.index];
        pkt->size     = buf.bytesused;
#if FF_API_DESTRUCT_PACKET
569
FF_DISABLE_DEPRECATION_WARNINGS
570
        pkt->destruct = dummy_release_buffer;
571
FF_ENABLE_DEPRECATION_WARNINGS
572 573 574
#endif

        buf_descriptor = av_malloc(sizeof(struct buff_data));
575
        if (!buf_descriptor) {
576 577 578 579
            /* 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");
580
            enqueue_buffer(s, &buf);
581 582 583

            return AVERROR(ENOMEM);
        }
584
        buf_descriptor->index = buf.index;
585 586 587 588 589
        buf_descriptor->s     = s;

        pkt->buf = av_buffer_create(pkt->data, pkt->size, mmap_release_buffer,
                                    buf_descriptor, 0);
        if (!pkt->buf) {
590
            av_log(ctx, AV_LOG_ERROR, "Failed to create a buffer\n");
591
            enqueue_buffer(s, &buf);
592 593 594
            av_freep(&buf_descriptor);
            return AVERROR(ENOMEM);
        }
595 596
    }
    pkt->pts = buf.timestamp.tv_sec * INT64_C(1000000) + buf.timestamp.tv_usec;
597
    convert_timestamp(ctx, &pkt->pts);
Luca Abeni's avatar
Luca Abeni committed
598

599
    return pkt->size;
Luca Abeni's avatar
Luca Abeni committed
600 601
}

602
static int mmap_start(AVFormatContext *ctx)
Luca Abeni's avatar
Luca Abeni committed
603
{
604
    struct video_data *s = ctx->priv_data;
Luca Abeni's avatar
Luca Abeni committed
605 606 607 608
    enum v4l2_buf_type type;
    int i, res;

    for (i = 0; i < s->buffers; i++) {
609 610 611 612 613
        struct v4l2_buffer buf = {
            .type   = V4L2_BUF_TYPE_VIDEO_CAPTURE,
            .index  = i,
            .memory = V4L2_MEMORY_MMAP
        };
Luca Abeni's avatar
Luca Abeni committed
614

615 616
        if (v4l2_ioctl(s->fd, VIDIOC_QBUF, &buf) < 0) {
            res = AVERROR(errno);
Luca Barbato's avatar
Luca Barbato committed
617
            av_log(ctx, AV_LOG_ERROR, "ioctl(VIDIOC_QBUF): %s\n",
618
                   av_err2str(res));
619
            return res;
Luca Abeni's avatar
Luca Abeni committed
620 621
        }
    }
622
    s->buffers_queued = s->buffers;
Luca Abeni's avatar
Luca Abeni committed
623 624

    type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
625 626
    if (v4l2_ioctl(s->fd, VIDIOC_STREAMON, &type) < 0) {
        res = AVERROR(errno);
Luca Barbato's avatar
Luca Barbato committed
627
        av_log(ctx, AV_LOG_ERROR, "ioctl(VIDIOC_STREAMON): %s\n",
628
               av_err2str(res));
629
        return res;
Luca Abeni's avatar
Luca Abeni committed
630 631 632 633 634 635 636 637 638 639 640 641 642 643
    }

    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...
     */
644
    v4l2_ioctl(s->fd, VIDIOC_STREAMOFF, &type);
Luca Abeni's avatar
Luca Abeni committed
645
    for (i = 0; i < s->buffers; i++) {
646
        v4l2_munmap(s->buf_start[i], s->buf_len[i]);
Luca Abeni's avatar
Luca Abeni committed
647
    }
648 649
    av_freep(&s->buf_start);
    av_freep(&s->buf_len);
Luca Abeni's avatar
Luca Abeni committed
650 651
}

652
static int v4l2_set_parameters(AVFormatContext *ctx)
653
{
654
    struct video_data *s = ctx->priv_data;
655
    struct v4l2_standard standard = { 0 };
656
    struct v4l2_streamparm streamparm = { 0 };
657
    struct v4l2_fract *tpf;
658
    AVRational framerate_q = { 0 };
659
    int i, ret;
660

Luca Barbato's avatar
Luca Barbato committed
661 662
    if (s->framerate &&
        (ret = av_parse_video_rate(&framerate_q, s->framerate)) < 0) {
663
        av_log(ctx, AV_LOG_ERROR, "Could not parse framerate '%s'.\n",
Luca Barbato's avatar
Luca Barbato committed
664
               s->framerate);
665 666
        return ret;
    }
667

668
    if (s->standard) {
669
        if (s->std_id) {
670
            ret = 0;
671
            av_log(ctx, AV_LOG_DEBUG, "Setting standard: %s\n", s->standard);
672 673 674
            /* set tv standard */
            for (i = 0; ; i++) {
                standard.index = i;
675
                if (v4l2_ioctl(s->fd, VIDIOC_ENUMSTD, &standard) < 0) {
676
                    ret = AVERROR(errno);
677 678 679
                    break;
                }
                if (!av_strcasecmp(standard.name, s->standard))
680 681 682
                    break;
            }
            if (ret < 0) {
683
                av_log(ctx, AV_LOG_ERROR, "Unknown or unsupported standard '%s'\n", s->standard);
684
                return ret;
685 686 687
            }

            if (v4l2_ioctl(s->fd, VIDIOC_S_STD, &standard.id) < 0) {
688
                ret = AVERROR(errno);
689
                av_log(ctx, AV_LOG_ERROR, "ioctl(VIDIOC_S_STD): %s\n", av_err2str(ret));
690
                return ret;
691 692
            }
        } else {
693
            av_log(ctx, AV_LOG_WARNING,
694 695 696 697 698 699 700 701
                   "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++) {
702
            standard.index = i;
703 704
            if (v4l2_ioctl(s->fd, VIDIOC_ENUMSTD, &standard) < 0) {
                ret = AVERROR(errno);
705 706 707 708 709
                if (ret == AVERROR(EINVAL)
#ifdef ENODATA
                    || ret == AVERROR(ENODATA)
#endif
                ) {
710 711 712
                    tpf = &streamparm.parm.capture.timeperframe;
                    break;
                }
713
                av_log(ctx, AV_LOG_ERROR, "ioctl(VIDIOC_ENUMSTD): %s\n", av_err2str(ret));
714
                return ret;
715 716
            }
            if (standard.id == s->std_id) {
717
                av_log(ctx, AV_LOG_DEBUG,
718
                       "Current standard: %s, id: %"PRIx64", frameperiod: %d/%d\n",
719
                       standard.name, (uint64_t)standard.id, tpf->numerator, tpf->denominator);
720
                break;
721
            }
722
        }
723 724 725
    } else {
        tpf = &streamparm.parm.capture.timeperframe;
    }
726

727 728
    streamparm.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    if (v4l2_ioctl(s->fd, VIDIOC_G_PARM, &streamparm) < 0) {
729
        ret = AVERROR(errno);
730
        av_log(ctx, AV_LOG_ERROR, "ioctl(VIDIOC_G_PARM): %s\n", av_err2str(ret));
731
        return ret;
732
    }
733

734
    if (framerate_q.num && framerate_q.den) {
735 736 737
        if (streamparm.parm.capture.capability & V4L2_CAP_TIMEPERFRAME) {
            tpf = &streamparm.parm.capture.timeperframe;

738
            av_log(ctx, AV_LOG_DEBUG, "Setting time per frame to %d/%d\n",
739
                   framerate_q.den, framerate_q.num);
740 741
            tpf->numerator   = framerate_q.den;
            tpf->denominator = framerate_q.num;
742

743
            if (v4l2_ioctl(s->fd, VIDIOC_S_PARM, &streamparm) < 0) {
744
                ret = AVERROR(errno);
745 746
                av_log(ctx, AV_LOG_ERROR, "ioctl(VIDIOC_S_PARM): %s\n",
                       av_err2str(ret));
747
                return ret;
748 749 750 751
            }

            if (framerate_q.num != tpf->denominator ||
                framerate_q.den != tpf->numerator) {
752
                av_log(ctx, AV_LOG_INFO,
753 754 755 756 757 758
                       "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 {
759
            av_log(ctx, AV_LOG_WARNING,
760
                   "The driver does not permit changing the time per frame\n");
761
        }
762
    }
763
    if (tpf->denominator > 0 && tpf->numerator > 0) {
764 765 766
        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;
767
    } else
768
        av_log(ctx, AV_LOG_WARNING, "Time per frame unknown\n");
769

770 771 772
    return 0;
}

773
static int device_try_init(AVFormatContext *ctx,
774 775 776 777 778
                           enum AVPixelFormat pix_fmt,
                           int *width,
                           int *height,
                           uint32_t *desired_format,
                           enum AVCodecID *codec_id)
779
{
780
    int ret, i;
781

782
    *desired_format = ff_fmt_ff2v4l(pix_fmt, ctx->video_codec_id);
783

784
    if (*desired_format) {
785
        ret = device_init(ctx, width, height, *desired_format);
786 787 788 789 790 791 792 793
        if (ret < 0) {
            *desired_format = 0;
            if (ret != AVERROR(EINVAL))
                return ret;
        }
    }

    if (!*desired_format) {
794
        for (i = 0; ff_fmt_conversion_table[i].codec_id != AV_CODEC_ID_NONE; i++) {
795
            if (ctx->video_codec_id == AV_CODEC_ID_NONE ||
796
                ff_fmt_conversion_table[i].codec_id == ctx->video_codec_id) {
797
                av_log(ctx, AV_LOG_DEBUG, "Trying to set codec:%s pix_fmt:%s\n",
798 799
                       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"));
800

801
                *desired_format = ff_fmt_conversion_table[i].v4l2_fmt;
802
                ret = device_init(ctx, width, height, *desired_format);
803
                if (ret >= 0)
804
                    break;
805 806 807
                else if (ret != AVERROR(EINVAL))
                    return ret;
                *desired_format = 0;
808 809
            }
        }
Luca Barbato's avatar
Luca Barbato committed
810

811
        if (*desired_format == 0) {
812
            av_log(ctx, AV_LOG_ERROR, "Cannot find a proper format for "
813
                   "codec '%s' (id %d), pixel format '%s' (id %d)\n",
814
                   avcodec_get_name(ctx->video_codec_id), ctx->video_codec_id,
815 816 817
                   (char *)av_x_if_null(av_get_pix_fmt_name(pix_fmt), "none"), pix_fmt);
            ret = AVERROR(EINVAL);
        }
818 819
    }

820
    *codec_id = ff_fmt_v4l2codec(*desired_format);
821 822
    av_assert0(*codec_id != AV_CODEC_ID_NONE);
    return ret;
823 824
}

825 826 827 828 829 830 831
static int v4l2_read_probe(AVProbeData *p)
{
    if (av_strstart(p->filename, "/dev/video", NULL))
        return AVPROBE_SCORE_MAX - 1;
    return 0;
}

832
static int v4l2_read_header(AVFormatContext *ctx)
Luca Abeni's avatar
Luca Abeni committed
833
{
834
    struct video_data *s = ctx->priv_data;
Luca Abeni's avatar
Luca Abeni committed
835
    AVStream *st;
836
    int res = 0;
837
    uint32_t desired_format;
Stephan Hilb's avatar
Stephan Hilb committed
838
    enum AVCodecID codec_id = AV_CODEC_ID_NONE;
839
    enum AVPixelFormat pix_fmt = AV_PIX_FMT_NONE;
840
    struct v4l2_input input = { 0 };
Luca Abeni's avatar
Luca Abeni committed
841

842
    st = avformat_new_stream(ctx, NULL);
843 844
    if (!st)
        return AVERROR(ENOMEM);
Luca Abeni's avatar
Luca Abeni committed
845

846 847 848
#if CONFIG_LIBV4L2
    /* silence libv4l2 logging. if fopen() fails v4l2_log_file will be NULL
       and errors will get sent to stderr */
849 850
    if (s->use_libv4l2)
        v4l2_log_file = fopen("/dev/null", "w");
851 852
#endif

853
    s->fd = device_open(ctx);
854 855
    if (s->fd < 0)
        return s->fd;
856

857 858
    if (s->channel != -1) {
        /* set video input */
859
        av_log(ctx, AV_LOG_DEBUG, "Selecting input_channel: %d\n", s->channel);
860 861
        if (v4l2_ioctl(s->fd, VIDIOC_S_INPUT, &s->channel) < 0) {
            res = AVERROR(errno);
862
            av_log(ctx, AV_LOG_ERROR, "ioctl(VIDIOC_S_INPUT): %s\n", av_err2str(res));
863
            goto fail;
864 865 866 867 868
        }
    } else {
        /* get current video input */
        if (v4l2_ioctl(s->fd, VIDIOC_G_INPUT, &s->channel) < 0) {
            res = AVERROR(errno);
869
            av_log(ctx, AV_LOG_ERROR, "ioctl(VIDIOC_G_INPUT): %s\n", av_err2str(res));
870
            goto fail;
871
        }
872 873
    }

874
    /* enum input */
875 876
    input.index = s->channel;
    if (v4l2_ioctl(s->fd, VIDIOC_ENUMINPUT, &input) < 0) {
877
        res = AVERROR(errno);
878
        av_log(ctx, AV_LOG_ERROR, "ioctl(VIDIOC_ENUMINPUT): %s\n", av_err2str(res));
879
        goto fail;
880 881
    }
    s->std_id = input.std;
882
    av_log(ctx, AV_LOG_DEBUG, "Current input_channel: %d, input_name: %s, input_std: %"PRIx64"\n",
883
           s->channel, input.name, (uint64_t)input.std);
884

885
    if (s->list_format) {
886
        list_formats(ctx, s->list_format);
887 888
        res = AVERROR_EXIT;
        goto fail;
889
    }
Luca Abeni's avatar
Luca Abeni committed
890

891
    if (s->list_standard) {
892
        list_standards(ctx);
893 894
        res = AVERROR_EXIT;
        goto fail;
895 896
    }

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

899
    if (s->pixel_format) {
900 901 902
        AVCodec *codec = avcodec_find_decoder_by_name(s->pixel_format);

        if (codec)
903
            ctx->video_codec_id = codec->id;
904 905 906

        pix_fmt = av_get_pix_fmt(s->pixel_format);

907
        if (pix_fmt == AV_PIX_FMT_NONE && !codec) {
908
            av_log(ctx, AV_LOG_ERROR, "No such input format: %s.\n",
909 910
                   s->pixel_format);

911 912
            res = AVERROR(EINVAL);
            goto fail;
913
        }
914
    }
Luca Abeni's avatar
Luca Abeni committed
915

916
    if (!s->width && !s->height) {
917
        struct v4l2_format fmt = { .type = V4L2_BUF_TYPE_VIDEO_CAPTURE };
918

919
        av_log(ctx, AV_LOG_VERBOSE,
Luca Barbato's avatar
Luca Barbato committed
920
               "Querying the device for the current frame size\n");
921
        if (v4l2_ioctl(s->fd, VIDIOC_G_FMT, &fmt) < 0) {
922
            res = AVERROR(errno);
923 924
            av_log(ctx, AV_LOG_ERROR, "ioctl(VIDIOC_G_FMT): %s\n",
                   av_err2str(res));
925
            goto fail;
926
        }
Luca Barbato's avatar
Luca Barbato committed
927

928 929
        s->width  = fmt.fmt.pix.width;
        s->height = fmt.fmt.pix.height;
930
        av_log(ctx, AV_LOG_VERBOSE,
Luca Barbato's avatar
Luca Barbato committed
931
               "Setting frame size to %dx%d\n", s->width, s->height);
932 933
    }

934
    res = device_try_init(ctx, pix_fmt, &s->width, &s->height, &desired_format, &codec_id);
935 936
    if (res < 0)
        goto fail;
Stephan Hilb's avatar
Stephan Hilb committed
937 938 939 940 941

    /* 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
     */
942 943
    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
944

945
    if ((res = av_image_check_size(s->width, s->height, 0, ctx)) < 0)
946
        goto fail;
Luca Barbato's avatar
Luca Barbato committed
947

948
    s->pixelformat = desired_format;
Luca Abeni's avatar
Luca Abeni committed
949

950 951 952
    if ((res = v4l2_set_parameters(ctx)) < 0)
        goto fail;

953
    st->codec->pix_fmt = ff_fmt_v4l2ff(desired_format, codec_id);
Luca Barbato's avatar
Luca Barbato committed
954 955 956
    s->frame_size =
        avpicture_get_size(st->codec->pix_fmt, s->width, s->height);

957 958
    if ((res = mmap_init(ctx)) ||
        (res = mmap_start(ctx)) < 0)
959
            goto fail;
960

961
    s->top_field_first = first_field(s);
Luca Abeni's avatar
Luca Abeni committed
962

963
    st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
964
    st->codec->codec_id = codec_id;
965
    if (codec_id == AV_CODEC_ID_RAWVIDEO)
966 967
        st->codec->codec_tag =
            avcodec_pix_fmt_to_codec_tag(st->codec->pix_fmt);
968 969 970
    else if (codec_id == AV_CODEC_ID_H264) {
        st->need_parsing = AVSTREAM_PARSE_HEADERS;
    }
971 972
    if (desired_format == V4L2_PIX_FMT_YVU420)
        st->codec->codec_tag = MKTAG('Y', 'V', '1', '2');
973 974
    else if (desired_format == V4L2_PIX_FMT_YVU410)
        st->codec->codec_tag = MKTAG('Y', 'V', 'U', '9');
975 976
    st->codec->width = s->width;
    st->codec->height = s->height;
977 978
    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
979

980
    return 0;
981 982 983 984

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

987
static int v4l2_read_packet(AVFormatContext *ctx, AVPacket *pkt)
Luca Abeni's avatar
Luca Abeni committed
988
{
989 990
    struct video_data *s = ctx->priv_data;
    AVFrame *frame = ctx->streams[0]->codec->coded_frame;
Luca Abeni's avatar
Luca Abeni committed
991 992
    int res;

993
    av_init_packet(pkt);
994
    if ((res = mmap_read_frame(ctx, pkt)) < 0) {
995
        return res;
Luca Abeni's avatar
Luca Abeni committed
996 997
    }

Luca Barbato's avatar
Luca Barbato committed
998 999 1000
    if (frame && s->interlaced) {
        frame->interlaced_frame = 1;
        frame->top_field_first = s->top_field_first;
Luca Abeni's avatar
Luca Abeni committed
1001 1002
    }

1003
    return pkt->size;
Luca Abeni's avatar
Luca Abeni committed
1004 1005
}

1006
static int v4l2_read_close(AVFormatContext *ctx)
Luca Abeni's avatar
Luca Abeni committed
1007
{
1008
    struct video_data *s = ctx->priv_data;
Luca Abeni's avatar
Luca Abeni committed
1009

1010
    if (avpriv_atomic_int_get(&s->buffers_queued) != s->buffers)
1011
        av_log(ctx, AV_LOG_WARNING, "Some buffers are still owned by the caller on "
1012 1013
               "close.\n");

1014
    mmap_close(s);
Luca Abeni's avatar
Luca Abeni committed
1015

1016
    v4l2_close(s->fd);
Luca Abeni's avatar
Luca Abeni committed
1017 1018 1019
    return 0;
}

1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094
static int v4l2_is_v4l_dev(const char *name)
{
    return !strncmp(name, "video", 5) ||
           !strncmp(name, "radio", 5) ||
           !strncmp(name, "vbi", 3) ||
           !strncmp(name, "v4l-subdev", 10);
}

static int v4l2_get_device_list(AVFormatContext *ctx, AVDeviceInfoList *device_list)
{
    struct video_data *s = ctx->priv_data;
    DIR *dir;
    struct dirent *entry;
    AVDeviceInfo *device = NULL;
    struct v4l2_capability cap;
    int ret = 0;

    if (!device_list)
        return AVERROR(EINVAL);

    dir = opendir("/dev");
    if (!dir) {
        ret = AVERROR(errno);
        av_log(ctx, AV_LOG_ERROR, "Couldn't open the directory: %s\n", av_err2str(ret));
        return ret;
    }
    while ((entry = readdir(dir))) {
        if (!v4l2_is_v4l_dev(entry->d_name))
            continue;

        snprintf(ctx->filename, sizeof(ctx->filename), "/dev/%s", entry->d_name);
        if ((s->fd = device_open(ctx)) < 0)
            continue;

        if (v4l2_ioctl(s->fd, VIDIOC_QUERYCAP, &cap) < 0) {
            ret = AVERROR(errno);
            av_log(ctx, AV_LOG_ERROR, "ioctl(VIDIOC_QUERYCAP): %s\n", av_err2str(ret));
            goto fail;
        }

        device = av_mallocz(sizeof(AVDeviceInfo));
        if (!device) {
            ret = AVERROR(ENOMEM);
            goto fail;
        }
        device->device_name = av_strdup(ctx->filename);
        device->device_description = av_strdup(cap.card);
        if (!device->device_name || !device->device_description) {
            ret = AVERROR(ENOMEM);
            goto fail;
        }

        if ((ret = av_dynarray_add_nofree(&device_list->devices,
                                          &device_list->nb_devices, device)) < 0)
            goto fail;

        v4l2_close(s->fd);
        s->fd = -1;
        continue;

      fail:
        if (device) {
            av_freep(&device->device_name);
            av_freep(&device->device_description);
            av_freep(&device);
        }
        if (s->fd >= 0)
            v4l2_close(s->fd);
        s->fd = -1;
        break;
    }
    closedir(dir);
    return ret;
}

1095 1096
#define OFFSET(x) offsetof(struct video_data, x)
#define DEC AV_OPT_FLAG_DECODING_PARAM
1097

1098
static const AVOption options[] = {
1099
    { "standard",     "set TV standard, used only by analog frame grabber",       OFFSET(standard),     AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0,       DEC },
1100
    { "channel",      "set TV channel, used only by frame grabber",               OFFSET(channel),      AV_OPT_TYPE_INT,    {.i64 = -1 },  -1, INT_MAX, DEC },
1101 1102 1103 1104 1105 1106 1107 1108 1109 1110
    { "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" },

1111 1112 1113
    { "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" },

1114 1115 1116 1117 1118
    { "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" },
1119
    { "use_libv4l2",  "use libv4l2 (v4l-utils) conversion functions",             OFFSET(use_libv4l2),  AV_OPT_TYPE_INT,    {.i64 = 0}, 0, 1, DEC },
1120 1121 1122 1123 1124 1125 1126 1127
    { NULL },
};

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

1131
AVInputFormat ff_v4l2_demuxer = {
1132
    .name           = "video4linux2,v4l2",
1133 1134
    .long_name      = NULL_IF_CONFIG_SMALL("Video4Linux2 device grab"),
    .priv_data_size = sizeof(struct video_data),
1135
    .read_probe     = v4l2_read_probe,
1136 1137 1138
    .read_header    = v4l2_read_header,
    .read_packet    = v4l2_read_packet,
    .read_close     = v4l2_read_close,
1139
    .get_device_list = v4l2_get_device_list,
1140 1141
    .flags          = AVFMT_NOFILE,
    .priv_class     = &v4l2_class,
Luca Abeni's avatar
Luca Abeni committed
1142
};