Re: V4l programming problem while grabbing frames in sequence...

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



Heavystation System Manager wrote:

Hi all,

I'm learning to use v4l module tring to write an application that captures
more frames in sequence (like xawtv)... but, i noticed that the ioctl,
with VIDIOCMCAPTURE as argument, needs too much time for its execution!
bringing to an excessive time between two different grabbed frames. I
don't know if it's a problem of my cheap webcam (a Trust SpaceC@M 300 with
ov511+ chipset) or my early experience of v4l programming (i think my
early experience, because this webcam works very well with xawtv)...

The function grab() is inspired by a procedure explained in a previous
mail sent from "Nemosoft Unv." with subject "RE:  sync: input/output
error" that i took as example form this experiment...

The function looks like this:

int grab(int video_fd,int w,int h,int format,int nframes)
{
        int frmbuf,frames = 0;
        struct video_mbuf buffer;
        struct video_mmap map;
        void * grabarea;

        if( ioctl(video_fd,VIDIOCGMBUF,&buffer) == -1 ) return (-1);

        grabarea = mmap(NULL,buffer.size,PROT_READ,MAP_SHARED,video_fd,0);

        if( grabarea == MAP_FAILED ) return (-2);

        map.frame       = 0;
        map.width       = w;
        map.height      = h;
        map.format      = format;

        // MCAPTURE(0)
        if( ioctl(video_fd,VIDIOCMCAPTURE,&map) == -1 ) return (-4);

        do
        {
                // SYNC(0)
                frmbuf = 0;
                if( ioctl(video_fd,VIDIOCSYNC,&frmbuf) == -1 )
                 return (-5);

                // MCAPTURE(1)
                map.frame       = 1;
                if( ioctl(video_fd,VIDIOCMCAPTURE,&map) == -1 )
                 return (-4);

                // Do something with frame 0...
                // ...

                // SYNC(1)
                frmbuf = 1;
                if( ioctl(video_fd,VIDIOCSYNC,&frmbuf) == -1 )
                 return (-5);

                // MCAPTURE(0)
                map.frame       = 0;
                if( ioctl(video_fd,VIDIOCMCAPTURE,&map) == -1 )
                  return (-4);

                // Do something with frame 1...
                // ...

                ++frames;

        }while( frames < nframes );

        // SYNC(0)
        frmbuf = 0;
        if( ioctl(video_fd,VIDIOCSYNC,&frmbuf) == -1 ) return (-5);

        munmap(grabarea,buffer.size);

        return (0);
}

What's wrong???

Thanks in advance!!


To get high throughput, you must queue them up as fast as possible:

int grab(int video_fd,int w,int h,int format,int nframes)
{
        int frmbuf,frames = 0;
        struct video_mbuf buffer;
        struct video_mmap map;
        void * grabarea;

        if( ioctl(video_fd,VIDIOCGMBUF,&buffer) == -1 ) return (-1);

        grabarea = mmap(NULL,buffer.size,PROT_READ,MAP_SHARED,video_fd,0);

        if( grabarea == MAP_FAILED ) return (-2);

        map.frame       = 0;
        map.width       = w;
        map.height      = h;
        map.format      = format;

        // MCAPTURE(0)
        if( ioctl(video_fd,VIDIOCMCAPTURE,&map) == -1 ) return (-4);
	// MCAPTURE(1)
	map.frame	= 1;
	if( ioctl(video_fd,VIDIOCMCAPTURE,&map) == -1 ) return (-4);

        do
        {
                // SYNC(0)
                frmbuf = 0;
                if( ioctl(video_fd,VIDIOCSYNC,&frmbuf) == -1 )
                 return (-5);

		// Do something with frame 0...
		// ...

                // MCAPTURE(0)
                map.frame       = 0;
                if( ioctl(video_fd,VIDIOCMCAPTURE,&map) == -1 )
                 return (-4);


                // SYNC(1)
                frmbuf = 1;
                if( ioctl(video_fd,VIDIOCSYNC,&frmbuf) == -1 )
                 return (-5);

		// Do something with frame 1...
		// ...

                // MCAPTURE(1)
                map.frame       = 1;
                if( ioctl(video_fd,VIDIOCMCAPTURE,&map) == -1 )
                  return (-4);

                ++frames;

        }while( frames < nframes );

        // SYNC(0)
        frmbuf = 0;
        if( ioctl(video_fd,VIDIOCSYNC,&frmbuf) == -1 ) return (-5);

        munmap(grabarea,buffer.size);

        return (0);
}

This way the buffers are queued as far in advance as possible, and you should have the lowest possible latency.

-justin





[Index of Archives]     [Linux DVB]     [Video Disk Recorder]     [Asterisk]     [Photo]     [DCCP]     [Netdev]     [Xorg]     [Util Linux NG]     [Xfree86]     [Free Photo Albums]     [Fedora Users]     [Fedora Women]     [ALSA Users]     [ALSA Devel]     [Linux USB]

Powered by Linux