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が終了。