Re: frame buffer

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



Edgard Alexander Sotter wrote:
> 
> Hi  Justin, I have some questions about your code:
> 
> > for(frame=0; frame<vm.frames; frame++);
> > {
> >     mm.frame = frame;
> >     if(ioctl(fd, VIDIOCMCAPTURE, &mm)<0)
> >     {
> >         perror("VIDIOCMCAPTURE");
> >         exit(-1);
> >     }
> > }
> 
> 1. Why did you do this routine if you going to make a  MCAPTURE again in this
> routine:
> 
>  mm.frame = frame;
>     if(ioctl(fd, VIDIOCMCAPTURE, &mm)<0)
>     {
>         perror("VIDIOCMCAPTURE");
>         exit(-1);
>     }
>     frame++;
>     if (frame>=vm.frames) frame = 0;

CMCAPTURE places a buffer on the driver's internal queue.  We therefore
start by placing all availlable buffers on the queue, so that the driver
can capture data to them.  We then call CSYNC, which will wait till the
buffer has valid data, then remove it from the capture queue.  Once we
have finished with the data, call CMCAPTURE again to capture more data
to the buffer.  The process looks as follows (the number in brackets is
the frame being operated on):

CMCAPTURE(0)
CMCAPTURE(1) - both buffers are now waiting to receive data
CSYNC(0) - wait for buffer 0 to have valid data.
[process data in buffer 0] - while this is happening buffer 1 is 
			     still on the capture queue, and receiving data.
CMCAPTURE(0) - when we have finished with the data in buffer 0, 
			     place it back in the queue for fresh data.
CSYNC(1) wait for buffer 1 to have valid data (buffer 1 was still
filling
			     while we were processing buffer 0.
[process data in buffer 1] - while this is happening, buffer 0 is back
on 
			     the capture queue, and receiving data.
CMCAPTURE(1) - when we have finished with the data in buffer 1, place it 
			     back in the queue for fresh data.
 ...

This way we ensure that while we are busy using the data in one buffer
in our application, the other buffer is available to the driver for
capturing data.  If you DON'T queue both buffers first you get the
following situation:

CMCAPTURE(0) - queue buffer 0 for fresh data
CSYNC(0) - wait for buffer 0 to have valid data.
[process data in buffer 0] - No other buffers are queued, so any
incomming data is lost.
CMCAPTURE(1) - queue buffer 1 for fresh data
CSYNC(1) - wait for buffer 1 to have valid data.
[process data in buffer 1] - No other buffers are queued, so any
incomming data is lost.

So you will capture at the most 50% of the incomming frames (usually
less due to latencies).

> 2. Why did you make this routine to make SYNC (is it not enough with the ioctl
> call??) and why didn't you put &mm but &frame???:
> 
> > {
> >     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;
> >     }
> >

Any signals received in the CSYNC call will interrupt the call, and it
will return early (without having actually dequeued the buffer). So, we
wait in a loop for CSYNC to return without an error, or a interrupt
restart.

-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