// gcc -std=gnu99 -ggdb -L /home/gjasny/src/libv4l-0.3.7/libv4l2 -L /home/gjasny/src/libv4l-0.3.7/libv4lconvert -I/home/gjasny/src/libv4l-0.3.7/include -lv4l2 -lv4lconvert -o reqbufs reqbufs.c #include #include #include #include #include #include #include #include #include #include #if 1 # include # define my_ioctl v4l2_ioctl # define my_open v4l2_open # define my_close v4l2_close # define my_mmap v4l2_mmap #else # define my_ioctl ioctl # define my_open open # define my_close close # define my_mmap mmap #endif #define NBUFFERS 2 #define WIDTH 352 #define HEIGHT 288 struct buffer { void *start; size_t length; } g_buffers[NBUFFERS]; static int xioctl( int fd, unsigned long int request, void *arg ) { int r; do r = my_ioctl (fd, request, arg); while (r == -1 && errno == EINTR); return r; } int main(int argc, char *argv[]) { const char *device = "/dev/video0"; int fd = my_open (device, O_RDWR); if (!fd) { perror ("open"); return -1; } struct v4l2_format format; memset( &format, 0, sizeof(struct v4l2_format)); format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; format.fmt.pix.width = WIDTH; format.fmt.pix.height = HEIGHT; format.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV; format.fmt.pix.field = V4L2_FIELD_ANY; if (xioctl (fd, VIDIOC_S_FMT, &format) == -1) { perror("ioctl (VIDIOC_S_FMT)"); return -1; } // init mmap struct v4l2_requestbuffers m_req; memset( &m_req, 0, sizeof(struct v4l2_requestbuffers) ); m_req.count = NBUFFERS; m_req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; m_req.memory = V4L2_MEMORY_MMAP; if (xioctl (fd, VIDIOC_REQBUFS, &m_req) == -1) { if (EINVAL == errno) { fprintf (stderr, "device does not support memory mapping.\n"); } else { perror ("ioctl (VIDIOC_REQBUFS)"); } return -1; } if (m_req.count < NBUFFERS) { fprintf (stderr, "Insufficient buffer memory.\n"); return -1; } for (unsigned i = 0; i < m_req.count; ++i) { struct v4l2_buffer buf; memset( &buf, 0, sizeof(buf) ); buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; buf.memory = V4L2_MEMORY_MMAP; buf.index = i; if (xioctl (fd, VIDIOC_QUERYBUF, &buf) == -1) { perror("ioctl (VIDIOC_QUERYBUF)"); return -1; } g_buffers[i].length = buf.length; g_buffers[i].start = my_mmap (NULL /* start anywhere */, buf.length, PROT_READ | PROT_WRITE /* required */, MAP_SHARED /* recommended */, fd, buf.m.offset); if (g_buffers[i].start == MAP_FAILED) { perror("mmap"); return -1; } } for (unsigned i = 0; i < NBUFFERS; ++i) { struct v4l2_buffer buf; memset( &buf, 0, sizeof(buf) ); buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; buf.memory = V4L2_MEMORY_MMAP; buf.index = i; if (xioctl (fd, VIDIOC_QBUF, &buf) == -1) { perror ("ioctl (VIDIOC_QBUF)"); return -1; } } enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE; if (xioctl (fd, VIDIOC_STREAMON, &type) == -1) { perror("ioctl (VIDIOC_STREAMON)"); return -1; } my_close (fd); return -1; }