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