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