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 > > volodya@xxxxxxxxxxxxxx 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 > Video4linux-list@xxxxxxxxxx > https://listman.redhat.com/mailman/listinfo/video4linux-list >