OpenCV : VIDIOC_REQBUFS: Cannot allocate memory

I don’t have any suggestions to your OpenCV issue, but …
maybe it would help if you try to take pictures with an other software like mplayer and than use opencv for imageprocessing.
you can take pictures for example 9 pictures in png format with typing into the terminal:
mplayer -vo png -frames 9 tv://

if you try to imageprocessing afterwards, please tell if it works, thanks!

Thank you for your suggestions but I am stuck with OpenCV and have to use it.
BTW, I observed following in dmesg when VIDIOC_REQBUFS request is sent to ioctl().

[ 637.752929] ------------[ cut here ]------------
[ 637.752990] WARNING: at mm/page_alloc.c:2109 __alloc_pages_nodemask+0xf5/0x3de()
[ 637.752990] Modules linked in: fuse joydev bufferclass_ti(O) omaplfb(O) pvrsrvkm(O) ip_tables x_tables g_mass_storage rfcomm ircomm_tty ircomm irda hidp bluetooth rfkill ipv6
[ 637.753082] [] (unwind_backtrace+0x1/0x8c) from [] (warn_slowpath_common+0x33/0x48)
[ 637.753112] [] (warn_slowpath_common+0x33/0x48) from [] (warn_slowpath_null+0xf/0x10)
[ 637.753143] [] (warn_slowpath_null+0xf/0x10) from [] (__alloc_pages_nodemask+0xf5/0x3de)
[ 637.753173] [] (__alloc_pages_nodemask+0xf5/0x3de) from [] (__dma_alloc+0x87/0x1fc)
[ 637.753204] [] (__dma_alloc+0x87/0x1fc) from [] (dma_alloc_coherent+0x33/0x3c)
[ 637.753234] [] (dma_alloc_coherent+0x33/0x3c) from [] (vb2_dma_contig_alloc+0x29/0x7a)
[ 637.753265] [] (vb2_dma_contig_alloc+0x29/0x7a) from [] (__vb2_queue_alloc+0x79/0x214)
[ 637.753295] [] (__vb2_queue_alloc+0x79/0x214) from [] (vb2_reqbufs+0x141/0x1da)
[ 637.753326] [] (vb2_reqbufs+0x141/0x1da) from [] (__video_do_ioctl+0x102f/0x363e)
[ 637.753356] [] (__video_do_ioctl+0x102f/0x363e) from [] (video_usercopy+0x1f7/0x2f4)
[ 637.753356] [] (video_usercopy+0x1f7/0x2f4) from [] (v4l2_ioctl+0x3b/0xb0)
[ 637.753387] [] (v4l2_ioctl+0x3b/0xb0) from [] (do_vfs_ioctl+0x327/0x370)
[ 637.753417] [] (do_vfs_ioctl+0x327/0x370) from [] (sys_ioctl+0x2d/0x44)
[ 637.753448] [] (sys_ioctl+0x2d/0x44) from [] (ret_fast_syscall+0x1/0x44)
[ 637.753479] —[ end trace b53ac4d9fccc31d9 ]—
[ 637.753479] cssp-camera cssp-camera: dma_alloc_coherent of size 0 failed

Is it because of less memory? I added 1GB swap partition also but no change in the behavior.

Thanks,
Linux Omicron

The only reliable way to fix this issue is to allocate memory once during boot and do not release it.

I am not sure about the driver you are using, but if driver doesn’t support it, you have to modify the driver for the same.

You can refer to the drivers/media/video/omap_vout.c for the reference where we do exactly same thing.

Thanks,

Vaibhav

I am using the driver supplied with Angstrom for BB-BONE-CAM3-01. (I guess it is cssp_camera driver)
I am surprised to see that the issue always occurs when I run an OpenCV application with the cape.
If I run a small application for v4l2 capture, the application would not throw the error 8 out of 10 times.
More surprising part is that OpenCV application runs perfectly for USB camera on the same environment.

Could you please elaborate about “to allocate memory once during boot and do not release it”. How do I do that?

Thank you,
Linux Omicron

During driver probe you can allocate memory pool for your required size and use it everytime you call REQBUF ioctl; that way you will make sure that driver always will have memory allocated with him and kernel memory pool will not be fragmented.

As mentioned in my last response you can refer to the omap_vout.c driver probe function, where we use bootargs “videoX_numbuffers” and “videoX_bufsize” and allocate this memory during boot itself. So everytime when call land in REQBUF, driver will not try to allocate new memory, and will return buffer from already allocated pool.

Thanks,

Vaibhav

Did you ever manage to find a simple fix to this problem? I am trying to do the same thing, and it seems like there has to be a simpler fix than recompiling the driver.

Hello, sorry for my English, is not my native language.

For the problem with Opencv and the cape camera Beaglebone can be solve with utilization of the library v4l2 " video for linux 2 ".
The call do by Opencv at v4l2 is wrong for the cape camera. You should put in your code :

static void xioctl(int fh, unsigned long int request, void *arg)
{
r_xioctl=100;
do {
r_xioctl = v4l2_ioctl(fh, request, arg);
} while (r_xioctl == -1 && ((errno == EINTR) || (errno == EAGAIN)));

if (r_xioctl == -1) {
fprintf(stderr, “error %d, %s\n”, errno, strerror(errno));
exit(EXIT_FAILURE);
}
}

// Next initialize capture

fd = v4l2_open(dev_name, O_RDWR | O_NONBLOCK, 0);
if (fd < 0) {
perror(“Cannot open device”);
exit(EXIT_FAILURE);
}
CLEAR(fmt);
fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
fmt.fmt.pix.width = width;
fmt.fmt.pix.height = height;
fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_RGB24;
fmt.fmt.pix.field = V4L2_FIELD_INTERLACED;
xioctl(fd, VIDIOC_S_FMT, &fmt);
if (fmt.fmt.pix.pixelformat != V4L2_PIX_FMT_RGB24) {
printf(“Libv4l didn’t accept RGB24 format. Can’t proceed.\n”);
exit(EXIT_FAILURE);
}
if ((fmt.fmt.pix.width != width) || (fmt.fmt.pix.height != height))
printf(“Warning: driver is sending image at %dx%d\n”,
fmt.fmt.pix.width, fmt.fmt.pix.height);
CLEAR(req);
req.count = 2;
req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
req.memory = V4L2_MEMORY_MMAP;
xioctl(fd, VIDIOC_REQBUFS, &req);
buff = (char*) calloc (1, sizeof (buffers));
buffers = (buffer
) buff;
for (n_buffers = 0; n_buffers < req.count; ++n_buffers) {
CLEAR(buf);
buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
buf.memory = V4L2_MEMORY_MMAP;
buf.index = n_buffers;
xioctl(fd, VIDIOC_QUERYBUF, &buf);
buffers[n_buffers].length = buf.length;
buffers[n_buffers].start = v4l2_mmap(NULL, buf.length,
PROT_READ | PROT_WRITE, MAP_SHARED,
fd, buf.m.offset);
if (MAP_FAILED == buffers[n_buffers].start) {
perror(“mmap”);
exit(EXIT_FAILURE);
}
}
for (i = 0; i < n_buffers; ++i) {
CLEAR(buf);
buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
buf.memory = V4L2_MEMORY_MMAP;
buf.index = i;
xioctl(fd, VIDIOC_QBUF, &buf);
}
type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
xioctl(fd, VIDIOC_STREAMON, &type);
imagemat = Mat(height, width, CV_8UC3, (void*)buffers[buf.index].start);
image = new IplImage(imagemat);

// next refresh the image

do {
FD_ZERO(&fds);
FD_SET(fd, &fds);
/* Timeout. /
tv.tv_sec = 0;
tv.tv_usec = 0;
r = select(fd + 1, &fds, NULL, NULL, &tv);
} while ((r == -1 && (errno = EINTR)));
if (r == -1) {
perror(“select”);
return errno;
}
CLEAR(buf);
buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
buf.memory = V4L2_MEMORY_MMAP;
xioctl(fd, VIDIOC_DQBUF, &buf);
imagemat = Mat(height, width, CV_8UC3, (void
)buffers[buf.index].start);
image = new IplImage(imagemat);
xioctl(fd, VIDIOC_QBUF, &buf);