Re: frame buffer

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



"Gleicon S. Moraes" wrote:
> 
> Edgard Alexander Sotter wrote:
> 
> [snip]
> 
> > someone told me that I have to work with video_buffer struct,
> > anyone has experience in work with this struct???... anyone has a example of
> > grabbing image in real time (video)??? using more than one buffer.
> >
> 
> I uploaded an attempt to use the double buffers to grab.
> My primary source of information were the Programming txt found in xawtv
> tarball.
> The link is the same:
> 
> http://planeta.terra.com.br/informatica/gleicon/videodog.html
> 
> The process looks is: sync buffer one, grab buffer 2, sync buffer 2,
> grab buffer 1.
> I hope it helps, sorry but I did it in a hurry, its not the nicest code
> overthere ... BTW if somebody got some clue to help improve this double
> buffer grab code, I would thank a lot. Probably I will do a presentation
> about video processing using linux, and would be very cool if I got some
> almost-real time processing :-D
> 
> Regards.

Here is a non-bttv specific example. I no longer use v4l, so I can't
test it... (Also, not all the initialisation code is here.)

/* START HERE */

struct video_mmap mm;
struct video_mbuf vm;
char *bigbuf;
char *buf;
int frame;
int i;

/* Query the actual buffers available */
if(ioctl(fd, VIDIOCGMBUF, &vm)<0)
{
    perror("VIDIOCGMBUF");
    exit(-1);
}
/* MMap all available buffers */
bigbuf = (char *)mmap(0, vm.size, PROT_READ|PROT_WRITE, MAP_SHARED, fd,
0);
if (bigbuf==(unsigned char *)-1)
{
   perror("mmap");
   exit(-1);
}     
/* Queue all available buffers for capture */
mm.height = h; /* Your own height */
mm.width  = w; /* Your own width */
mm.format = VIDEO_PALETTE_YUV420P; /* Your own format */
for(frame=0; frame<vm.frames; frame++);
{
    mm.frame = frame; 
    if(ioctl(fd, VIDIOCMCAPTURE, &mm)<0)
    {
        perror("VIDIOCMCAPTURE");
        exit(-1);
    }
}
frame = 0;
while(!done)
{
    i = -1;
    while(i<0)
    {
         i = ioctl(cap_fd, VIDIOCSYNC, &frame);
         if(i < 0 && errno == EINTR) continue;
         if(i < 0)
         {
               perror("VIDIOCSYNC");
               /* You may want to exit here, because something has gone
pretty badly wrong... */
         }
         break;
    }

    buf = bigbuf + vm.offsets[frame];
    /* Process the frame data pointed to by buf */
    /* Once buf is no longer in use by the application... */

    mm.frame = frame; 
    if(ioctl(fd, VIDIOCMCAPTURE, &mm)<0)
    {
        perror("VIDIOCMCAPTURE");
        exit(-1);
    }
    frame++;
    if (frame>=vm.frames) frame = 0;
}

/* END HERE */

I am fairly sure that this is the "correct" way to do things acording to
the V4L spec - it makes no assumptions about the number of buffers,
instead, it uses whatever buffers are available from the driver.  Note
that the API spec requires.

Also, please note that to be formally correct, the app must first test
for streaming capabilities with VIDIOCGCAP, and set the picture format
with VIDIOCSPICT (before any call to VIDIOCGMBUF is made).

I would appreciat it if this code could be checked + tested + completed
(all init code), and then placed in some sort of an application writer's
guide, so that more v4l apps will be v4l compliant rather than bttv
compliant:-(

A vast number of v4l apps (yes, including some I wrote) are extremely
bttv specific (hardcoded buffer offsets, hardcoded buffer counts, no use
of SPICT, etc.), and this is leading to some pretty serious abuse of the
v4l spec (and a few "your driver is broken" complaints when the driver
is actually correct!).

Thanks

-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