Re: OpenCV : VIDIOC_REQBUFS: Cannot allocate memory

2,246 views
Skip to first unread message

alex....@gmail.com

unread,
Mar 21, 2013, 11:46:19 AM3/21/13
to beagl...@googlegroups.com
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!



Am Mittwoch, 20. März 2013 23:28:38 UTC-7 schrieb linux....@gmail.com:
Hello All,

I am working on a project with BeagleBone and 3.1 MP camera cape.
The OS is Angstrorm : Linux beaglebone 3.2.34 #1 Wed Nov 21 14:17:11 CET 2012
I noticed that camera works well with cheese and mplayer but it doesn't work with a simple OpenCV application to capture video from the camera.

My application to capture video returns after following errors. It seems that application doesn't able to get past to the call cvCaptureFromCAM.

VIDIOC_REQBUFS: Cannot allocate memory
munmap: Invalid argument
munmap: Invalid argument
munmap: Invalid argument
munmap: Invalid argument
Unable to stop the stream.: Bad file descriptor
munmap: Invalid argument
munmap: Invalid argument
munmap: Invalid argument
munmap: Invalid argument
Floating point exception

Running v4l2-ctl gives following information. Is it usual that the camera doesn't use libv4l2?

root@beaglebone:~# v4l2-ctl --info
Driver Info (not using libv4l2):
        Driver name   : cssp_camera
        Card type     : cssp_camera
        Bus info      : cssp_camera-000
        Driver version: 3.2.34
        Capabilities  : 0x05000001
                Video Capture
                Read/Write
                Streaming

Any direction to make the camera work with OpenCV?

Thank you,
Linux Omicron

linux....@gmail.com

unread,
Mar 23, 2013, 4:39:23 AM3/23/13
to beagl...@googlegroups.com
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] [<c000f8d1>] (unwind_backtrace+0x1/0x8c) from [<c002cd07>] (warn_slowpath_common+0x33/0x48)
[  637.753112] [<c002cd07>] (warn_slowpath_common+0x33/0x48) from [<c002cd2b>] (warn_slowpath_null+0xf/0x10)
[  637.753143] [<c002cd2b>] (warn_slowpath_null+0xf/0x10) from [<c007061f>] (__alloc_pages_nodemask+0xf5/0x3de)
[  637.753173] [<c007061f>] (__alloc_pages_nodemask+0xf5/0x3de) from [<c0010e97>] (__dma_alloc+0x87/0x1fc)
[  637.753204] [<c0010e97>] (__dma_alloc+0x87/0x1fc) from [<c001105b>] (dma_alloc_coherent+0x33/0x3c)
[  637.753234] [<c001105b>] (dma_alloc_coherent+0x33/0x3c) from [<c02233bb>] (vb2_dma_contig_alloc+0x29/0x7a)
[  637.753265] [<c02233bb>] (vb2_dma_contig_alloc+0x29/0x7a) from [<c0221c85>] (__vb2_queue_alloc+0x79/0x214)
[  637.753295] [<c0221c85>] (__vb2_queue_alloc+0x79/0x214) from [<c022221b>] (vb2_reqbufs+0x141/0x1da)
[  637.753326] [<c022221b>] (vb2_reqbufs+0x141/0x1da) from [<c0218559>] (__video_do_ioctl+0x102f/0x363e)
[  637.753356] [<c0218559>] (__video_do_ioctl+0x102f/0x363e) from [<c02173e7>] (video_usercopy+0x1f7/0x2f4)
[  637.753356] [<c02173e7>] (video_usercopy+0x1f7/0x2f4) from [<c02169b3>] (v4l2_ioctl+0x3b/0xb0)
[  637.753387] [<c02169b3>] (v4l2_ioctl+0x3b/0xb0) from [<c00940a3>] (do_vfs_ioctl+0x327/0x370)
[  637.753417] [<c00940a3>] (do_vfs_ioctl+0x327/0x370) from [<c0094119>] (sys_ioctl+0x2d/0x44)
[  637.753448] [<c0094119>] (sys_ioctl+0x2d/0x44) from [<c000c441>] (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

Hiremath, Vaibhav

unread,
Mar 25, 2013, 12:45:19 AM3/25/13
to beagl...@googlegroups.com

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

--
For more options, visit http://beagleboard.org/discuss
---
You received this message because you are subscribed to the Google Groups "BeagleBoard" group.
To unsubscribe from this group and stop receiving emails from it, send an email to beagleboard...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
 
 

linux....@gmail.com

unread,
Mar 25, 2013, 2:16:23 AM3/25/13
to beagl...@googlegroups.com, hvai...@ti.com
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

Hiremath, Vaibhav

unread,
Mar 25, 2013, 2:21:24 AM3/25/13
to linux....@gmail.com, beagl...@googlegroups.com

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

Walter Schilling

unread,
Nov 7, 2013, 11:25:46 PM11/7/13
to beagl...@googlegroups.com, hvai...@ti.com
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.

merle.m...@gmail.com

unread,
Mar 9, 2014, 12:18:18 PM3/9/14
to beagl...@googlegroups.com, hvai...@ti.com

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);

ajbla...@gmail.com

unread,
Mar 31, 2014, 11:18:01 AM3/31/14
to beagl...@googlegroups.com
Has anyone come up with a solution for this?  I've tried both the Angstrom and Debian images as well as the V4l2 grabber code that was posted above, but all produce the memory allocation error.  Cheese can capture images.  It looks like cheese uses a custom camera object based on GLib.  Is there no way to use openCV or V4l2 to capture directly from the cape?  Thanks,

aj

ajbla...@gmail.com

unread,
Jul 11, 2014, 5:13:57 PM7/11/14
to beagl...@googlegroups.com, ajbla...@gmail.com
Here's a quick update on my progress and the kludge I've been using.  I've tried every combination of V4l2 settings I could find but could not get any too work.  I then tried V4l2ucp which did work.  Looking at the source code it calls mplayer to display the video.  Mplayer also worked well, and it uses V4l2 to capture images from the cape.  I've resorted to calling mplayer from Qt and having it dump several images to files, then I read in the files with opencv and do the processing I need.  It works but is definitely a kludge.  If anyone knows or can figure out what V4l2 settings mplayer uses then we could grab directly from the camera.
Reply all
Reply to author
Forward
0 new messages