Thread: updated dma to user space API
Brought to you by:
aeb,
bencollins
From: Sebastien R. <Seb...@sy...> - 2000-04-25 10:21:41
|
I have updated the API for the direct iso dma to user space feature that is available for the ohci driver. Previously the buffer filling was running continuously in the driver, and the user app was only waiting for irq generated for each frame. The problem was doing so you could easily create synchronization problems. Now the user app has to queue the buffers for each frame. If the user app can not keep up with the framerate, the dma context will wait until fresh buffers are queued. It is very similar to the video4linux API. The driver has been tested with 1-2 cameras on the bus, each delivering uncompressed 640x480 YUV422 30Hz video. Works well so far (at least the display is nice). NOTE 1: the driver is probably not safe for SMP machines (will do that later). It might also not be wise to share the device /dev/ohci1394 between several threads/processes. NOTE 2: you still have to enable this feature in ohci1394.h. It seems quite stable now, but I want to wait for some comment/bug reports before enabling it by default. The user app now looks like this: main() { int fd; struct video1394_mmap v; struct video1394_wait w; char *map; v.channel = 0; /* the iso channel you want to listen to */ v.sync_tag = 1; /* the tag in the iso packet for frame sync */ v.nb_buffers = 4; /* the number of buffers you want */ v.buf_size = 320*240*2; /* the size in bytes of one frame */ /* open the driver */ fd = open("/dev/ohci1394",O_RDWR); /* launch the iso context that will do the dma transfer * !!! NOTE: the field v.buf_size is modified by this call !!! * !!! it is rounded up to a multiple of PAGE_SIZE !!! */ if (ioctl(fd, VIDEO1394_LISTEN_CHANNEL, &v)<0) { perror("VIDEO1394_LISTEN_CHANNEL"); } /* map the dma buffer into user space */ if ((map = (char *) mmap(0,v.nb_buffers*v.buf_size, PROT_READ|PROT_WRITE, MAP_SHARED, fd,0)) == (char *)-1) { perror("mmap"); return -1; } w.channel = v.channel; /* queue the buffers for frame acquisition */ for (i=0;i<v.nb_buffers;i++) { w.buffer=i; if (ioctl(fd,VIDEO1394_QUEUE_BUFFER,&w)==-1) { perror("VIDEO1394_QUEUE_BUFFER"); return -1; } /* here you do the camera initialization, start iso transmission */ ........ /* */ w.buffer=0; while(cond) { /* wait for the next frame */ ioctl(fd, VIDEO1394_WAIT_BUFFER, &w); /* put the buffer again in the queue */ ioctl(fd,VIDEO1394_QUEUE_BUFFER, &w); /* the image buffer starts at map+w.buffer*v.buf_size, * and has for length the frame size specified at the * beginning of the program. Here you do whatever you * want with it */ ....... w.buffer = (w.buffer+1)%v.nb_buffers; } /* here you stop iso transmission */ ........ /* */ /* unmap the memory */ if (map!=(char*)-1) munmap(map,v.nb_buffers*v.buf_size); /* deallocate the iso context */ if (ioctl(fd, VIDEO1394_UNLISTEN_CHANNEL, &v.channel)<0) { perror("VIDEO1394_UNLISTEN_CHANNEL"); } /* close the device */ close(fd); } |
From: Maxim S. S. <ma...@st...> - 2000-04-26 20:57:49
|
> you could easily create synchronization problems. Now the user app > has to queue the buffers for each frame. If the user app can not keep > up with the framerate, the dma context will wait until fresh buffers > are queued. It is very similar to the video4linux API. This is the same as MS stack does, though MS does not support it for umode apps - only for other kmode drivers. Max |
From: Andreas B. <and...@mu...> - 2000-04-28 16:14:54
|
On Tue, Apr 25, 2000 at 08:14:57PM +1000, Sebastien Rougeaux wrote: > > I have updated the API for the direct iso dma to user space feature > that is available for the ohci driver. Previously the buffer filling > was running continuously in the driver, and the user app was only > waiting for irq generated for each frame. The problem was doing so > you could easily create synchronization problems. Now the user app > has to queue the buffers for each frame. If the user app can not keep > up with the framerate, the dma context will wait until fresh buffers > are queued. It is very similar to the video4linux API. Is there anything special about this DMA? I guess it just does header stripping instead of giving the complete packet like libraw does. Strictly seen it's also not DMA to user space but having kernel buffers mapped to user space (what I intended to do for libraw once I figure it out and get to it). What I have problems with is that it duplicates a lot of bttv code, something Linus probably will also complain about. Plus, from my understanding, the bttv code handles a lot of cases which are not required for OHCI hardware. What I have in mind for better iso receiving is something like a manager part in the subsystem handing out chunks of 64kB (or something, should be tunable) contiguous mem to the hardware drivers which receive iso packets into those. When the remaining space in the chunk is too small for more packets, the driver tells the subsystem and gets a new chunk. The filled chunks have then a soft and a hard reference count. The soft count indicates that someone is interested in the contained data at all (otherwise it could just as well be freed immediately). The hard count indicates that it must not be freed at this time (e.g. it's mapped to user space by raw1394 currently). If a limit is reached or memory gets low the oldest chunks with soft references but no hard refs can be freed (i.e. packets get lost). > /* queue the buffers for frame acquisition */ > for (i=0;i<v.nb_buffers;i++) { > w.buffer=i; > if (ioctl(fd,VIDEO1394_QUEUE_BUFFER,&w)==-1) { > perror("VIDEO1394_QUEUE_BUFFER"); > return -1; } > } ^ In case anyone wondered there was a missing closing brace there. -- Andreas E. Bombe <and...@mu...> DSA key 0x04880A44 http://home.pages.de/~andreas.bombe/ http://linux1394.sourceforge.net/ |
From: Sebastien R. <Seb...@sy...> - 2000-04-30 10:15:37
|
>>>>> "Andreas" == Andreas Bombe <and...@mu...> writes: Andreas> On Tue, Apr 25, 2000 at 08:14:57PM +1000, Sebastien Rougeaux wrote: >> I have updated the API for the direct iso dma to user space feature that >> is available for the ohci driver. Previously the buffer filling was running >> continuously in the driver, and the user app was only waiting for irq >> generated for each frame. The problem was doing so you could easily create >> synchronization problems. Now the user app has to queue the buffers for >> each frame. If the user app can not keep up with the framerate, the dma >> context will wait until fresh buffers are queued. It is very similar to the >> video4linux API. Andreas> Is there anything special about this DMA? I guess it just does Andreas> header stripping instead of giving the complete packet like libraw Andreas> does. Strictly seen it's also not DMA to user space but having Andreas> kernel buffers mapped to user space (what I intended to do for libraw Andreas> once I figure it out and get to it). Strictly speaking yes... Is there anything wrong with that ? It is what framegrabber drivers like bttv are doing... anyway I don't know any other way of doing it. If this feature could be included in libraw, it would be good... Andreas> What I have problems with is that it duplicates a lot of bttv code, Andreas> something Linus probably will also complain about. Plus, from my Andreas> understanding, the bttv code handles a lot of cases which are not Andreas> required for OHCI hardware. Yes it duplicates the bttv code for the buffer allocation and mapping. Again, if there is such function in the kernel, I would be happy to use it. If not we have to write something anyway... Andreas> What I have in mind for better iso receiving is something like a Andreas> manager part in the subsystem handing out chunks of 64kB (or Andreas> something, should be tunable) contiguous mem to the hardware drivers Andreas> which receive iso packets into those. When the remaining space in Andreas> the chunk is too small for more packets, the driver tells the Andreas> subsystem and gets a new chunk. Andreas> The filled chunks have then a soft and a hard reference count. The Andreas> soft count indicates that someone is interested in the contained data Andreas> at all (otherwise it could just as well be freed immediately). The Andreas> hard count indicates that it must not be freed at this time Andreas> (e.g. it's mapped to user space by raw1394 currently). If a limit is Andreas> reached or memory gets low the oldest chunks with soft references but Andreas> no hard refs can be freed (i.e. packets get lost). Sounds good. My code is temporary anyway (I needed the functionality ASAP so I wrote it as fast as I could). If you come up without something similar with no loss of performance, I'll be very interested. The important part for me is that the driver: . allows multi-buffering (tunable) . doesn't waste CPU time . does frame synchronization -- Sebastien Rougeaux RSISE, The Australian National University |
From: Manfred W. <e95...@st...> - 2000-05-02 21:25:44
|
Sebastien Rougeaux wrote: > The important part for me > is that the driver: > > . allows multi-buffering (tunable) > . doesn't waste CPU time > . does frame synchronization Of course not wasting CPU time is a very important topic concerning the reception of iso packets. But in the last issue (frame synchronisation) I do not aggree with you. That should not be done by the driver; any interpretation of the content of an iso packet should be done by the application. The driver shall deliver the raw packets (as libraw does now) and the application should decide, what the data is and whether it has to look for sync tags and things like that. One reason is, that there are many different data types transmitted via isochronous channels, not only plain video images. For example I receive MPEG 2 transport streams, and I want to get the packets as they are, the driver shall not interpret them. The only extension I could imagine is, that the driver could resolve the CIP-format (ie. Reassembling the source packets and either forwarding them to the application, when the time stamp [in the source packet header; that correspond to the least significant bytes of the 16 bits of the cycle time register] is reached or forwarding them immediately together with the timestamp); all further interpretation is up to the application. I believe, the interface for receiving iso packets, which libraw provides, is good. The only thing that might be changed is handling of the header; I already mentioned that byte-swapping would make sense for consistency. Of course the "low-level-handling" of these packets in the driver could (should) be optimated, but the interface in libraw should stay unchanged. Manfred Weihs PS: Did somebody read my posting about using the cycle time register for synchronisation (my whishlist entry)? Any comments? |