Corrupt images, when capturing images from multiple cameras using the V4L2 driver

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hello, 

I would like to grab images from multiple cameras under using the V4L2
API. I followed the presentation under found on
http://linuxtv.org/downloads/presentations/summit_jun_2010/20100206-fosdem.pdf 
used the code and adapted it sightly for my purpose. It works very well
for 1 camera.

However Once I begin to grab images from multiple cameras (successively)
I get corrupt images. I uploaded an example image to
http://www.directupload.net/file/d/3733/9c4jx3pv_png.htm

Although I set the right resolution for the camera (744 x 480), the
output of buffer.bytesused, after the VIDIOC_DQBUF does not correspond
with the expected value (744x480 = 357120). This would probably explain
the corrupt images.

The more camera I use, the less buffer.bytesused I get and the more
stripes are in the image. Could you please give me a hint, what am I
doing wrong ?

Thanks, Karel

Here is the minimal C code I use for my application:


int main()
{
	/* ##################### INIT ##################### */

	int numOfCameras = 6;
	int xRes = 744;
	int yRes = 480;
	int exposure = 2000;
	unsigned int timeBetweenSnapshots = 2; // in sec
	char fileName[sizeof "./output/image 000 from camera 0.PNG"];

	static const char *devices[] = { "/dev/video0", "/dev/video1",
"/dev/video2", "/dev/video3", "/dev/video4", "/dev/video5",
"/dev/video6", "/dev/video7" };

	struct v4l2_capability cap[8];
	struct v4l2_control control[8];
	struct v4l2_format format[8];
	struct v4l2_requestbuffers req[8];
	struct v4l2_buffer buffer[8];

	int type = V4L2_BUF_TYPE_VIDEO_CAPTURE; // had to declare the type here
because of the loop

	unsigned int i;
	unsigned int j;
	unsigned int k;

	int fd[8];
	void **mem[8];
	//unsigned char **mem[8];

	/* ##################### OPEN DEVICE ##################### */

	for (j = 0; j < numOfCameras; ++j) {

		fd[j] = open(devices[j], O_RDWR);
		ioctl(fd[j], VIDIOC_QUERYCAP, &cap[j]);


		/* ##################### CAM CONTROLL ############### */

		control[j].id = V4L2_CID_EXPOSURE_AUTO;
		control[j].value = V4L2_EXPOSURE_SHUTTER_PRIORITY;
		ioctl(fd[j], VIDIOC_S_CTRL, &control[j]);

		control[j].id = V4L2_CID_EXPOSURE_ABSOLUTE;
		control[j].value = exposure;
		ioctl(fd[j], VIDIOC_S_CTRL, &control[j]);

		/* ##################### FORMAT ##################### */

		ioctl(fd[j], VIDIOC_G_FMT, &format[j]);
		format[j].type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
		format[j].fmt.pix.width = xRes;
		format[j].fmt.pix.height = yRes;
		//format.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;
		format[j].fmt.pix.pixelformat = V4L2_PIX_FMT_GREY;
		ioctl(fd[j], VIDIOC_S_FMT, &format[j]);

		/* ##################### REQ BUF #################### */

		req[j].type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
		req[j].count = 4;
		req[j].memory = V4L2_MEMORY_MMAP;
		ioctl(fd[j], VIDIOC_REQBUFS, &req[j]);
		mem[j] = malloc(req[j].count * sizeof(*mem));

		/* ##################### MMAP ##################### */

		for (i = 0; i < req[j].count; ++i) {
			buffer[j].type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
			buffer[j].memory = V4L2_MEMORY_MMAP;
			buffer[j].index = i;
			ioctl(fd[j], VIDIOC_QUERYBUF, &buffer[j]);
			mem[j][i] = mmap(0, buffer[j].length,
					PROT_READ|PROT_WRITE,
					MAP_SHARED, fd[j], buffer[j].m.offset);
		}

		/* ##################### CREATE QUEUE ############### */

		for (i = 0; i < req[j].count; ++i) {
			buffer[j].type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
			buffer[j].memory = V4L2_MEMORY_MMAP;
			buffer[j].index = i;
			ioctl(fd[j], VIDIOC_QBUF, &buffer[j]);
		}

	} /* ### ### end of camera init ### ### */

	/* ##################### STREAM ON ##################### */
	for (j = 0; j < numOfCameras; ++j) {

		ioctl(fd[j], VIDIOC_STREAMON, &type);
	}


	/* ##################### GET FRAME ##################### */

	k = 0;
	while (!kbhit()){
		k ++;

		for (j = 0; j < numOfCameras; j++) {

			buffer[j].type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
			buffer[j].memory = V4L2_MEMORY_MMAP;
			usleep(100000);
			ioctl(fd[j], VIDIOC_DQBUF, &buffer[j]);
			printf("\nBuffer {%p}, Buf. Index %d, Buf. bytes used %d\n",
mem[j][buffer[j].index], buffer[j].index,  buffer[j].bytesused);

			// create filename
			sprintf(fileName, "./output/image %03d from camera %d.PNG", k, j);
			// save as PNG file
			saveToPng(mem[j][buffer[j].index], fileName, xRes, yRes);

			ioctl(fd[j], VIDIOC_QBUF, &buffer[j]);

			sleep(timeBetweenSnapshots);
		}
	}

	/* ##################### STREAM OFF ##################### */
	for (j = 0; j < numOfCameras; ++j) {

		ioctl(fd[j], VIDIOC_STREAMOFF, &type);
	}

	/* ##################### CLEANUP ##################### */

	for (j = 0; j < numOfCameras; ++j) {

		close(fd[j]);
		free(mem[j]);
	}

	return (0);
}

**********************************************************************
Leibniz-Institut für Agrartechnik Potsdam-Bornim e.V.
Max-Eyth-Allee 100
D-14469 Potsdam
 
Vorstand: 
Prof. Dr. Reiner Brunsch (Wissenschaftlicher Direktor)
Dr. Martin Geyer (Stellvertreter des Wissenschaftlichen Direktors)
Prof. Dr. Thomas Amon  (2. Stellvertreter des Wissenschaftlichen Direktors)
Dr. Uta Tietz (Verwaltungsleiterin) 
Amtsgericht Potsdam, VR 680 P, USt-ID DE811704150

**********************************************************************
This email and any files transmitted with it are confidential and
intended solely for the use of the individual or entity to whom they
are addressed. If you have received this email in error please notify
the system manager.

Scanned by the Clearswift SECURE Email Gateway.

www.clearswift.com
**********************************************************************
��.n��������+%������w��{.n�����{��g����^n�r������&��z�ޗ�zf���h���~����������_��+v���)ߣ�


[Index of Archives]     [Linux Input]     [Video for Linux]     [Gstreamer Embedded]     [Mplayer Users]     [Linux USB Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Yosemite Backpacking]
  Powered by Linux