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
next prev parent 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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.