On Thu, 25 Oct 2001, Ori Pessach wrote:
> Vladimir,
>
> Your proposal for the capture API via memory mapped buffers makes some rather
> naive assumptions about the order in which certain operations take place,
> resulting in a very real possiblity of unavoidable race conditions, and data
> corruption.
>
> You wrote:
>
> When capturing video the application will read data from the buffers
> until it encounters one with smaller serial number and/or marked as busy.
>
> It then has an option to do something else and/or issue a request
> on control interface to notify when more data is available.
>
> So, at the very least, the application has to read two fields from the
> struction, and test them, in order to stop capturing. The problem is that
> reading fields out of memory is not an atomic function. So, if you
> application does something like:
>
> if( !header->busy) /* HERE! */
> if(header->number > previous_frame)
> {
> capture_frame();
> }
>
> If an interrupt occurs where I marked "HERE!", and the driver starts a DMA
> operation into the buffer being tested, bad things will happen. The results
First of all, the only bad things that could happen is that the
application will get bad data - in case of video application data from
several frames.
Secondly, it is not as bad at it sounds. Why ?
a) these fields change slowly - video grabber is not likely
to fill more than 60 buffers per second
b) look at what's happening: we tested the timestamp and we know
that we are reading the next frame. Now suppose the data gets
overwritten in between. It means that all _other_ buffers were
filled and we are simply too slow processing one frame
c) in the case of slowly processing application (say we grab one
frame per second and then analyse it) the application is supposed
to copy the data into internal buffer.
d) but, what happens when we first mmapped the buffers. Which buffer
should we read ? One way would be to scan timestamp and busy
fields until we find the last buffer filled and work with it.
e) the application can test for the validity of the data by checking
busy and timestamp field during and after processing of the buffer
f) the logic I am using is actually quite similar to the logic that
serves read requests in bt848 driver (except that those request
end up in copy_to_user)
Hence, my assumptions are:
a) the application is able to recover in case it is reading bad data
from mmaped buffers
b) the time it takes to copy an entire buffer is much much smaller
then the rate at which new buffers are created (or we are screwed
anyway)
> will depend on the driver's implementation, on the device in question, and on
> sheer luck. As an example, the driver could mark the buffer 'busy', set the
> frame number, and start reading data, returning control to the user process
> before it's done reading. (This can happen with a bus mastering device). Now,
> the frame number is current, the second if() succeeds, and capture_frame()
> will capture something incoherent.
Umm. Perhaps I was not clear. The data interface is asynchronous. That is
the driver is capturing and updating data without any contact with
application. The application is able to determine driver status by
examining control struct.
The driver would work as follows:
* receive an interrupt signalling that new data is available
* find the buffer to write to (say by using a counter) and mark it
busy
* schedule/perform data transfer by either using DMA, memcpy or
something else (in case of USB webcam for example)
* once the transfer is complete update the timestamp and then
clear the busy flag.
>
> Also, I'm not sure how you can write device independant user code using your
> approach. It reminds me of several Microsoft API's I've worked with in the
> past (DirectX and SAPI come to mind), where driver implementers were given so
> much freedom in choosing which parts of the API to implement, that driver
> independant user code became either hard (in the case of DirectX) or
> impossible (SAPI) to implement.
This is a very valid concern, one that I though about for a while.
Even if we can enumerate the fields how do we know their semantic value ?
Will "busy" mean the same thing in every driver ?
The solution I see is that the driver will report one
or more "INTERFACE_CLASS"es it is compatible with. an interface class
specifies not only which fields _must_ be present, but also their semantic
meaning. For example "BASIC_GRABBER-YUV422" might mean the timestamp/busy
scheme I described above together with width/height/pitch fields and
YUV422 data in buffers. Any application that know what
BASIC_GRABBER-YUV422 will be able to use the device. On the other hand the
driver will also be able to offer extended functionality and, perhaps,
device specific classes meant to be used by device-specific applications.
The idea is that very new feature will first be implemented in
device-specific fashion (in addition to standard functionality). Then, an
RFC will determine the particular INTERFACE_CLASS specification and then
the drivers will be modified to support it.
There is also an issue of people implementing binary-only drivers with
hardware-specific interfaces - something occuring in Windows.
I believe that by requiring that the only interface is symbolic and having
the ability to monitor the data we will provide clear separation between
kernel and user-space and assure that any communication in between is
easily discoverable.
Vladimir Dergachev
>
> It also sounds a lot like what I read about Plan 9, which I haven't worked
> with. I hear that's not a bad thing.
>
> Ori Pessach
>
> [EMAIL PROTECTED] wrote:
>
> > After looking at and working with Xv, v4l and v4l2 I became somewhat
> > dissatisfied with the current state of affairs. I have attached a
> > description of the API that would make (at least) me much happier.
> >
> > I would very much appreciate comments from interested people..
> >
> > thanks !
> >
> > Vladimir Dergachev
> >
> > ------------------------------------------------------------------------
> > Name: km.rfc.txt
> > km.rfc.txt Type: Plain Text (TEXT/PLAIN)
> > Encoding: BASE64
> > Description: RFC: Kernel multimedia API (km.rfc.txt)
>
>
>
> _______________________________________________
> Video4linux-list mailing list
> [EMAIL PROTECTED]
> https://listman.redhat.com/mailman/listinfo/video4linux-list
>
_______________________________________________
Video4linux-list mailing list
[EMAIL PROTECTED]
https://listman.redhat.com/mailman/listinfo/video4linux-list