linux-media.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Alaganraj Sandhanam <alaganraj.sandhanam@gmail.com>
To: "\"Mácha, Karel\"" <KMacha@atb-potsdam.de>,
	"linux-media@vger.kernel.org" <linux-media@vger.kernel.org>
Subject: Re: Corrupt images, when capturing images from multiple cameras using the V4L2 driver
Date: Fri, 05 Sep 2014 01:41:56 +0530	[thread overview]
Message-ID: <5408C78C.2010608@gmail.com> (raw)
In-Reply-To: <BDE207EB81F3F14F85CFF86344BBE70E2D2FDF@saturn.atb-potsdam.de>

Hi Karel,

I suggest you to zero fill v4l2 structures before assign values also
check the return value of all ioctl call.
for example,

    struct v4l2_format fmt;

    memset(&fmt, 0, sizeof fmt);
    fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    fmt.fmt.pix.width = xRes;
    ret = ioctl(fd, VIDIOC_S_FMT, &fmt);
    if (ret < 0)
           printf("VIDIOC_S_FMT failed: %d\n", ret);

Please find comments in-line.

On Tuesday 02 September 2014 05:36 PM, Mácha, Karel wrote:
> 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;
As it works well for 1 camera, try with only 2 instead of 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]);
check the return value
> 
> 
> 		/* ##################### CAM CONTROLL ############### */
> 
zero fill control[j]
memset(control[j], 0, sizeof control[j]);
> 		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 ##################### */
> 
zero fill format[j]
memset(format[j], 0, sizeof format[j]);
> 		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 #################### */
> 
memset(req[j], 0, sizeof req[j]);
> 		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) {
                        memset(buffer[j], 0, sizeof buffer[j]);
> 			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) {
memset(buffer[j], 0, sizeof buffer[j]);
> 			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]);
check the return value
> 		}
> 
> 	} /* ### ### end of camera init ### ### */
> 
> 	/* ##################### STREAM ON ##################### */
> 	for (j = 0; j < numOfCameras; ++j) {
> 
> 		ioctl(fd[j], VIDIOC_STREAMON, &type);
> 	}
> 
> 
> 	/* ##################### GET FRAME ##################### */
> 
> 	k = 0;
> 	while (!kbhit()){
Instead of multiple frames, capture single frame and check the result.
> 		k ++;
> 
> 		for (j = 0; j < numOfCameras; j++) {
> 
    memset(buffer[j], 0, sizeof buffer[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�����r��y���b�X��ǧv�^�)޺{.n�+����{���bj)���w*\x1fjg���\x1e�����ݢj/���z�ޖ��2�ޙ���&�)ߡ�a��\x7f��\x1e�G���h�\x0f�j:+v���w�٥
> 

Regards,
Alaganraj

  reply	other threads:[~2014-09-04 20:12 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-09-02 12:06 Corrupt images, when capturing images from multiple cameras using the V4L2 driver Mácha, Karel
2014-09-04 20:11 ` Alaganraj Sandhanam [this message]
2014-09-05 12:39   ` Mácha, Karel
2014-09-08 12:02     ` Alaganraj

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=5408C78C.2010608@gmail.com \
    --to=alaganraj.sandhanam@gmail.com \
    --cc=KMacha@atb-potsdam.de \
    --cc=linux-media@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).