Beispiel #1
0
static int start_capturing(void) {
    unsigned int i;
    enum v4l2_buf_type type;

    for (i = 0; i < cam_n_buffers; i++) {
        struct v4l2_buffer buf;

        CLEAR(buf);

        buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
        buf.memory = V4L2_MEMORY_MMAP;
        buf.index = i;

        if (xioctl(cam_fd, VIDIOC_QBUF, &buf) == -1) {
            return errno_report("VIDIOC_QBUF");
        }

    }

    type = V4L2_BUF_TYPE_VIDEO_CAPTURE;

    if (xioctl(cam_fd, VIDIOC_STREAMON, &type)) {
        return errno_report("VIDIOC_STREAMON");
    }

    return 0;
}
Beispiel #2
0
static int init_device(void) {
    struct v4l2_capability cap;
    struct v4l2_cropcap cropcap;
    struct v4l2_crop crop;
    struct v4l2_format fmt;
    unsigned int min;

    if (xioctl(cam_fd, VIDIOC_QUERYCAP, &cap)) {
        if (EINVAL == errno) {
            fprintf(stderr, "%s is no V4L2 device\n", cam_dev_name);
            return -1;
        } else {
            return errno_report("VIDIOC_QUERYCAP");
        }
    }

    if (!(cap.capabilities & V4L2_CAP_VIDEO_CAPTURE)) {
        fprintf(stderr, "%s is no video capture device\n", cam_dev_name);
        return -1;
    }

    /* Using MMAP */
    if (!(cap.capabilities & V4L2_CAP_STREAMING)) {
        fprintf(stderr, "%s does not support streaming i/o\n", cam_dev_name);
        return -1;  
    }

    CLEAR(cropcap);
    cropcap.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;

    if (xioctl(cam_fd, VIDIOC_CROPCAP, &cropcap) == 0) {
        /* If cropping is supported, do not crop */
        crop.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
        crop.c = cropcap.defrect;
        xioctl(cam_fd, VIDIOC_S_CROP, &crop);
    }

    CLEAR(fmt);

    fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    fmt.fmt.pix.width = cam_width;
    fmt.fmt.pix.height = cam_height;
    fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;
    fmt.fmt.pix.field = V4L2_FIELD_NONE; /* No interlacing, please */

    if (xioctl(cam_fd, VIDIOC_S_FMT, &fmt) == -1) {
        return errno_report("VIDIOC_S_FMT");
    }

    /* Buggy driver paranoia. */
    min = fmt.fmt.pix.width * 2;
    if (fmt.fmt.pix.bytesperline < min) fmt.fmt.pix.bytesperline = min;
    min = fmt.fmt.pix.bytesperline * fmt.fmt.pix.height;
    if (fmt.fmt.pix.sizeimage < min) fmt.fmt.pix.sizeimage = min;

    return init_mmap();
}
Beispiel #3
0
static int init_mmap(void) {
    struct v4l2_requestbuffers req;

    CLEAR(req);
    req.count = 4;
    req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    req.memory = V4L2_MEMORY_MMAP;

    if (xioctl(cam_fd, VIDIOC_REQBUFS, &req) == -1) {
        if (errno == EINVAL) {
            fprintf(stderr, "%s does not support memory mapping\n", cam_dev_name);
            return -1;
        } else {
            return errno_report("VIDIOC_REQBUFS");
        }
    }

    if (req.count < 2) {
        fprintf(stderr, "Insufficient buffer memory on %s\n", cam_dev_name);
        return -1;
    }

    cam_buffers = (struct buffer*)calloc (req.count, sizeof(*cam_buffers));

    if (!cam_buffers) {
        fprintf(stderr, "Out of memory\n");
        return -1;
    }

    /* Stuff buffers with pretty things */
    for (cam_n_buffers = 0; cam_n_buffers < req.count; cam_n_buffers++) {
        struct v4l2_buffer buf;

        CLEAR(buf);

        buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
        buf.memory = V4L2_MEMORY_MMAP;
        buf.index = cam_n_buffers;

        if (xioctl(cam_fd, VIDIOC_QUERYBUF, &buf) == -1)
            return errno_report("VIDIOC_QUERYBUF");

        cam_buffers[cam_n_buffers].len = buf.length;
        cam_buffers[cam_n_buffers].start =
            mmap(NULL, buf.length, PROT_READ | PROT_WRITE, MAP_SHARED,
                cam_fd, buf.m.offset);

        if (cam_buffers[cam_n_buffers].start == MAP_FAILED)
            return errno_report("mmap");
    }

    return 0;
}
Beispiel #4
0
static int do_capture(void) {
    fd_set fds;
    struct timeval tv;
    int r;

    for (;;) { 
        FD_ZERO(&fds);
        FD_SET(cam_fd, &fds);

        /* Timeout. */
        tv.tv_sec = 2;
        tv.tv_usec = 0;

        r = select(cam_fd + 1, &fds, NULL, NULL, &tv);

        if (r == -1) {
            if (errno != EINTR) return errno_report("select");
        }
   
        if (r == 0) {
            fprintf(stderr, "select timeout\n");
            return -1;
        }

        if (read_frame() == 0) break;
    }

    return 0;
}
Beispiel #5
0
static int close_device(void) {
    if (close(cam_fd) == -1) {
        return errno_report("close_device()");
    }
    cam_fd = -1;

    return 0;
}
Beispiel #6
0
static int stop_capturing(void) {
    enum v4l2_buf_type type;

    type = V4L2_BUF_TYPE_VIDEO_CAPTURE;

    if (xioctl(cam_fd, VIDIOC_STREAMOFF, &type) == -1)
        return errno_report("VIDIOC_STREAMOFF");

    return 0;
}
Beispiel #7
0
static int uninit_device(void) {
    unsigned int i;

    for (i = 0; i < cam_n_buffers; i++) {
        if (munmap(cam_buffers[i].start, cam_buffers[i].len) == -1) {
            return errno_report("munmap");
        }
    }

    return 0;
}
Beispiel #8
0
static int read_frame(void) {
    struct v4l2_buffer buf;

    CLEAR(buf);
    buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    buf.memory = V4L2_MEMORY_MMAP;

    if (xioctl(cam_fd, VIDIOC_DQBUF, &buf)) {
        switch (errno) {
        case EAGAIN: return -1;

        case EIO:
        default: return errno_report("VIDIOC_DQBUF");
        }
    }

    process_image(cam_buffers[buf.index].start);

    if (xioctl(cam_fd, VIDIOC_QBUF, &buf) == -1) {
        return errno_report("VIDIOC_QBUF");
    }

    return 0;
}
Beispiel #9
0
struct buffer* 
oss_record(int fd) {
    if ((buffers[0].length = read(fd, buffers[0].start, buffers[0].length)) == -1)
        errno_report("Audio read");
    return buffers;
}