読者です 読者をやめる 読者になる 読者になる

luvcviewを読むその1

取り合えずまずopenを探す。
uvcvideo.cのinit_v4l2にある。

static int init_v4l2(struct vdIn *vd)
{
    int i;
    int ret = 0;

    if ((vd->fd = open(vd->videodevice, O_RDWR)) == -1) {
        perror("ERROR opening V4L interface");
        exit(1);
    }
    memset(&vd->cap, 0, sizeof(struct v4l2_capability));
    ret = ioctl(vd->fd, VIDIOC_QUERYCAP, &vd->cap);

まずオープンされる。
その後ret = ioctl(vd->fd, VIDIOC_QUERYCAP, &vd->cap);があるけどこれはカメラの情報取得かな。この後、ストリーミング可能かどうかを確認してるから。
んで次にストリーミング設定をするんだけど、まぁ詳細は飛ばして、まぁ構造体に値をセットしたあとに

   ret = ioctl(vd->fd, VIDIOC_S_PARM, setfps);

これで設定
んでその後

   ret = ioctl(vd->fd, VIDIOC_G_PARM, setfps);

これで設定ができてるかを確認。
その後にリクエストバッファ

    /* request buffers */
    memset(&vd->rb, 0, sizeof(struct v4l2_requestbuffers));
    vd->rb.count = NB_BUFFER;
    vd->rb.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    vd->rb.memory = V4L2_MEMORY_MMAP;

    ret = ioctl(vd->fd, VIDIOC_REQBUFS, &vd->rb);
    if (ret < 0) {
        perror("Unable to allocate buffers");
        goto fatal;
    }

んでNB_BUFFER回数分&vd->bufのバッファを確保して、mmapしてる。

    /* map the buffers */
    for (i = 0; i < NB_BUFFER; i++) {
        memset(&vd->buf, 0, sizeof(struct v4l2_buffer));
        vd->buf.index = i;
        vd->buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
        vd->buf.memory = V4L2_MEMORY_MMAP;
        ret = ioctl(vd->fd, VIDIOC_QUERYBUF, &vd->buf);
        if (ret < 0) {
            perror("Unable to query buffer");
            goto fatal;
        }
        if (debug)
            printf("length: %u offset: %u\n", vd->buf.length,
                    vd->buf.m.offset);
        vd->mem[i] = mmap(0 /* start anywhere */ ,
                vd->buf.length, PROT_READ, MAP_SHARED, vd->fd,
                vd->buf.m.offset);
        if (vd->mem[i] == MAP_FAILED) {
            perror("Unable to map buffer");
            goto fatal;
        }
        if (debug)
            printf("Buffer mapped at address %p.\n", vd->mem[i]);
    }

そして、

    /* Queue the buffers. */
    for (i = 0; i < NB_BUFFER; ++i) {
        memset(&vd->buf, 0, sizeof(struct v4l2_buffer));
        vd->buf.index = i;
        vd->buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
        vd->buf.memory = V4L2_MEMORY_MMAP;
        ret = ioctl(vd->fd, VIDIOC_QBUF, &vd->buf);
        if (ret < 0) {
            perror("Unable to queue buffer");
            goto fatal;;
        }
    }

バッファの並び替え?
これでinit_v4l2が終了。