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*jg��������ݢj/���z�ޖ��2�ޙ���&�)ߡ�a�����G���h��j:+v���w�٥
> 

Regards,
Alaganraj
--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to