v4l2Device::~v4l2Device() { if (m_fd > -1) { BYE_ON(close(m_fd) < 0, "V4L2 device close failed: %s\n", ERRSTR); } }
void v4l2Device::V4L2StopCapture() { int type = V4L2_BUF_TYPE_VIDEO_CAPTURE; int ret = 0; ret = blockIOCTL(m_fd, VIDIOC_STREAMOFF, &type); BYE_ON(ret < 0, "STREAMOFF failed: %s\n", ERRSTR); }
Buffer *v4l2Device::V4L2DeQueueBuffer(Buffer *buffer) { struct v4l2_buffer buf; int ret; memset(&buf, 0, sizeof buf); buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; buf.memory = V4L2_MEMORY_DMABUF; ret = blockIOCTL(m_fd, VIDIOC_DQBUF, &buf); BYE_ON(ret, "VIDIOC_DQBUF failed: %s\n", ERRSTR); return &buffer[buf.index]; }
void v4l2Device::V4L2QueueBuffer(Buffer *buffer) { struct v4l2_buffer buf; int ret; memset(&buf, 0, sizeof buf); buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; buf.memory = V4L2_MEMORY_DMABUF; buf.index = buffer->index; buf.m.fd = buffer->fd; ret = blockIOCTL(m_fd, VIDIOC_QBUF, &buf); BYE_ON(ret < 0, "VIDIOC_QBUF for buffer %d failed: %s (fd %u) (i %u)\n", buf.index, ERRSTR, buffer->fd, buffer->index); }
int main(int argc, char *argv[]) { int ret; struct setup s; ret = parse_args(argc, argv, &s); BYE_ON(ret, "failed to parse arguments\n"); BYE_ON(s.module[0] == 0, "DRM module is missing\n"); BYE_ON(s.video[0] == 0, "video node is missing\n"); int drmfd = drmOpen(s.module, NULL); BYE_ON(drmfd < 0, "drmOpen(%s) failed: %s\n", s.module, ERRSTR); int v4lfd = open(s.video, O_RDWR); BYE_ON(v4lfd < 0, "failed to open %s: %s\n", s.video, ERRSTR); struct v4l2_capability caps; memset(&caps, 0, sizeof caps); ret = ioctl(v4lfd, VIDIOC_QUERYCAP, &caps); BYE_ON(ret, "VIDIOC_QUERYCAP failed: %s\n", ERRSTR); /* TODO: add single plane support */ BYE_ON(~caps.capabilities & V4L2_CAP_VIDEO_CAPTURE, "video: singleplanar capture is not supported\n"); struct v4l2_format fmt; memset(&fmt, 0, sizeof fmt); fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; ret = ioctl(v4lfd, VIDIOC_G_FMT, &fmt); BYE_ON(ret < 0, "VIDIOC_G_FMT failed: %s\n", ERRSTR); printf("G_FMT(start): width = %u, height = %u, 4cc = %.4s\n", fmt.fmt.pix.width, fmt.fmt.pix.height, (char*)&fmt.fmt.pix.pixelformat); if (s.use_wh) { fmt.fmt.pix.width = s.w; fmt.fmt.pix.height = s.h; } if (s.in_fourcc) fmt.fmt.pix.pixelformat = s.in_fourcc; ret = ioctl(v4lfd, VIDIOC_S_FMT, &fmt); BYE_ON(ret < 0, "VIDIOC_S_FMT failed: %s\n", ERRSTR); ret = ioctl(v4lfd, VIDIOC_G_FMT, &fmt); BYE_ON(ret < 0, "VIDIOC_G_FMT failed: %s\n", ERRSTR); printf("G_FMT(final): width = %u, height = %u, 4cc = %.4s\n", fmt.fmt.pix.width, fmt.fmt.pix.height, (char*)&fmt.fmt.pix.pixelformat); struct v4l2_requestbuffers rqbufs; memset(&rqbufs, 0, sizeof(rqbufs)); rqbufs.count = s.buffer_count; rqbufs.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; rqbufs.memory = V4L2_MEMORY_DMABUF; ret = ioctl(v4lfd, VIDIOC_REQBUFS, &rqbufs); BYE_ON(ret < 0, "VIDIOC_REQBUFS failed: %s\n", ERRSTR); BYE_ON(rqbufs.count < s.buffer_count, "video node allocated only " "%u of %u buffers\n", rqbufs.count, s.buffer_count); s.in_fourcc = fmt.fmt.pix.pixelformat; s.w = fmt.fmt.pix.width; s.h = fmt.fmt.pix.height; /* TODO: add support for multiplanar formats */ struct buffer buffer[s.buffer_count]; uint32_t size = fmt.fmt.pix.sizeimage; uint32_t pitch = fmt.fmt.pix.bytesperline; printf("size = %u pitch = %u\n", size, pitch); for (unsigned int i = 0; i < s.buffer_count; ++i) { ret = buffer_create(&buffer[i], drmfd, &s, size, pitch); BYE_ON(ret, "failed to create buffer%d\n", i); } printf("buffers ready\n"); /*drmModeModeInfo drmmode; uint32_t con; ret = find_mode(&drmmode, drmfd, &s, &con); BYE_ON(ret, "failed to find valid mode\n"); ret = find_plane(drmfd, &s); BYE_ON(ret, "failed to find compatible plane\n");*/ for (unsigned int i = 0; i < s.buffer_count; ++i) { struct v4l2_buffer buf; memset(&buf, 0, sizeof buf); buf.index = i; buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; buf.memory = V4L2_MEMORY_DMABUF; buf.m.fd = buffer[i].dbuf_fd; ret = ioctl(v4lfd, VIDIOC_QBUF, &buf); BYE_ON(ret < 0, "VIDIOC_QBUF for buffer %d failed: %s (fd %u)\n", buf.index, ERRSTR, buffer[i].dbuf_fd); } int type = V4L2_BUF_TYPE_VIDEO_CAPTURE; ret = ioctl(v4lfd, VIDIOC_STREAMON, &type); BYE_ON(ret < 0, "STREAMON failed: %s\n", ERRSTR); struct pollfd fds[] = { { .fd = v4lfd, .events = POLLIN }, { .fd = drmfd, .events = POLLIN },
void v4l2Device::V4L2Init() { int ret; struct v4l2_format fmt; struct v4l2_capability caps; struct v4l2_streamparm parm; struct v4l2_requestbuffers rqbufs; CLEAR(parm); m_fd = open(m_devname, O_RDWR); BYE_ON(m_fd < 0, "failed to open %s: %s\n", m_devname, ERRSTR); CLEAR(caps); /* Specifically for setting up mipi configuration. DMABUFF is * also enable by default here. */ if (m_MipiPort > -1 && m_MipiMode != NONE) { parm.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; parm.parm.capture.capturemode = GetAtomISPModes(m_MipiMode); ret = blockIOCTL(m_fd, VIDIOC_S_INPUT, &m_MipiPort); BYE_ON(ret < 0, "VIDIOC_S_INPUT failed: %s\n", ERRSTR); ret = blockIOCTL(m_fd, VIDIOC_S_PARM, &parm); BYE_ON(ret < 0, "VIDIOC_S_PARAM failed: %s\n", ERRSTR); } ret = blockIOCTL(m_fd, VIDIOC_QUERYCAP, &caps); msdk_printf( "Driver Caps:\n" " Driver: \"%s\"\n" " Card: \"%s\"\n" " Bus: \"%s\"\n" " Version: %d.%d\n" " Capabilities: %08x\n", caps.driver, caps.card, caps.bus_info, (caps.version>>16)&&0xff, (caps.version>>24)&&0xff, caps.capabilities); BYE_ON(ret, "VIDIOC_QUERYCAP failed: %s\n", ERRSTR); BYE_ON(~caps.capabilities & V4L2_CAP_VIDEO_CAPTURE, "video: singleplanar capture is not supported\n"); CLEAR(fmt); fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; ret = blockIOCTL(m_fd, VIDIOC_G_FMT, &fmt); BYE_ON(ret < 0, "VIDIOC_G_FMT failed: %s\n", ERRSTR); msdk_printf("G_FMT(start): width = %u, height = %u, 4cc = %.4s, BPP = %u sizeimage = %d field = %d\n", fmt.fmt.pix.width, fmt.fmt.pix.height, (char*)&fmt.fmt.pix.pixelformat, fmt.fmt.pix.bytesperline, fmt.fmt.pix.sizeimage, fmt.fmt.pix.field); fmt.fmt.pix = m_format; msdk_printf("G_FMT(pre): width = %u, height = %u, 4cc = %.4s, BPP = %u sizeimage = %d field = %d\n", fmt.fmt.pix.width, fmt.fmt.pix.height, (char*)&fmt.fmt.pix.pixelformat, fmt.fmt.pix.bytesperline, fmt.fmt.pix.sizeimage, fmt.fmt.pix.field); ret = blockIOCTL(m_fd, VIDIOC_S_FMT, &fmt); BYE_ON(ret < 0, "VIDIOC_S_FMT failed: %s\n", ERRSTR); ret = blockIOCTL(m_fd, VIDIOC_G_FMT, &fmt); BYE_ON(ret < 0, "VIDIOC_G_FMT failed: %s\n", ERRSTR); msdk_printf("G_FMT(final): width = %u, height = %u, 4cc = %.4s, BPP = %u\n", fmt.fmt.pix.width, fmt.fmt.pix.height, (char*)&fmt.fmt.pix.pixelformat, fmt.fmt.pix.bytesperline); CLEAR(rqbufs); rqbufs.count = m_num_buffers; rqbufs.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; rqbufs.memory = V4L2_MEMORY_DMABUF; ret = blockIOCTL(m_fd, VIDIOC_REQBUFS, &rqbufs); BYE_ON(ret < 0, "VIDIOC_REQBUFS failed: %s\n", ERRSTR); BYE_ON(rqbufs.count < m_num_buffers, "video node allocated only " "%u of %u buffers\n", rqbufs.count, m_num_buffers); m_format = fmt.fmt.pix; }