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 2012I 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 memorymunmap: Invalid argumentmunmap: Invalid argumentmunmap: Invalid argumentmunmap: Invalid argumentUnable to stop the stream.: Bad file descriptormunmap: Invalid argumentmunmap: Invalid argumentmunmap: Invalid argumentmunmap: Invalid argumentFloating point exceptionRunning v4l2-ctl gives following information. Is it usual that the camera doesn't use libv4l2?root@beaglebone:~# v4l2-ctl --infoDriver Info (not using libv4l2):Driver name : cssp_cameraCard type : cssp_cameraBus info : cssp_camera-000Driver version: 3.2.34Capabilities : 0x05000001Video CaptureRead/WriteStreamingAny direction to make the camera work with OpenCV?Thank you,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
--
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.
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
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);