static int device_open(AVFormatContext *ctx)
{
    struct v4l2_capability cap;
    int fd;
    int res, err;
    int flags = O_RDWR;

    if (ctx->flags & AVFMT_FLAG_NONBLOCK) {
        flags |= O_NONBLOCK;
    }

    fd = open(ctx->filename, flags, 0);
    if (fd < 0) {
        err = errno;

        av_log(ctx, AV_LOG_ERROR, "Cannot open video device %s : %s\n",
               ctx->filename, strerror(err));

        return AVERROR(err);
    }

    res = ioctl(fd, VIDIOC_QUERYCAP, &cap);
    if (res < 0) {
        err = errno;
        av_log(ctx, AV_LOG_ERROR, "ioctl(VIDIOC_QUERYCAP): %s\n",
               strerror(err));

        goto fail;
    }

    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;

        goto fail;
    }

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

    return fd;

fail:
    close(fd);
    return AVERROR(err);
}