📄 readme.transfer
字号:
Transfer of data between userland and the hardware playback device------------------------------------------------------------------The driver provides two ways to send data; first is without copysecond is with copy.The transfer without copy is a bit more efficient regarding thehost computer CPU and memory load; but the difference is only noticeableon embedded platforms.All the explanations given in this file are about video data transferin the case of MPEG elementary streams, but are applicable to audio andother streams.Without copy------------The reference application is playasync.cIn this model, the kernel allocates specific buffers when runninginsmod:--------------------------------------------------------- (see realmagichwl.h)/// number of dma buffers allocated for asynchronous transfer. Maximum is 256#define ASYNCDMABUFFERS 16asyncdma.c:// size of an asynchronous dma buffer. Must be in [1<<10 (4 KBytes),1<<18 (256 KBytes)]#define ASYNCDMASIZE 32768------------------------------------------------------------------------------The user has to run mmap() calls to map these buffers for the application.They are mapped as a contiguous area of ASYNCDMABUFFERS*ASYNCDMASIZE in userland butshould always be though of as separate areas when writing applications:The idea is to maintain valid reference counters on these buffers, shared betweenuserland and kernelland. There is one reference counter per dma buffer.It does not make sense for RUA to try to send data overlapping two dmabuffers, and such a call will be rejected with return codeRUA_DECODER_FEEDME_ASYNC_ERROR_SPANNED. As a counterpart, sending awhole dma buffer or subsets of it is the way to go.It does not make sense as well to write an application read()ing data spanningover multiple dma buffers, because acquire/release logics will become quite complex.User has to ACQUIRE() the buffer before using (filling it), and RELEASE() afterall desired filling is done on the target DMA buffer.As expected, a successful RUA_DECODER_FEEDME_ASYNC() call does not mean the matchingdata has been sent and successfully decoded, hence the `asynchronous' name.Data will be fetched by EM84xx using DMA at random instants, and theinterrupt routine checks regularly which sections have been handled and candidatefor kernel RELEASE().When the application runs out of available buffers (meaning buffering is complete)it has to wait for the first dma buffer(s) to be released by the kernel.In the kernel, when the reference count on a specific DMA buffer fallsto zero, the happening REALMAGICHWL_HAPPENING_DECODER_DMABUFFER_FREEis raised and allows the user to be unlocked at the optimal instant to resumequeueing.Once this happening has been received, user has to query PROPID_KERNEL_ASYNCDMA_FreedAddress to get the freed addresses (as the baseuserland pointer of the mapped dma buffers) and run the appropriate code to handle _all_ of them (because a given freed address will occur only once).Remark 1User should not rely on the fact that addresses are freedchronologically [However, this is the case for playasync.c but may notbe true for more complex and multithreaded applications. Lookingcloser, the dma_inuse[] array in playasync.c is not necessary, but ishere to base alternate implementations on this code].Remark 2At a given instant, the total number of queued video packets cannot exceedthe microcode FIFO length (36 entries for video). This means that a typical applicationsending pointers to demuxed sections of a video stream of ~1900 bytes eachwill only be able to queue 60KB of data and does not use the DMA buffersat complete capacity. In this case, RUA_DECODER_FEEDME_ASYNC() fails with RUA_DECODER_FEEDME_ERROR_CANNOTQUEUE;another happening REALMAGICHWL_HAPPENING_DECODER_VIDEO_FIFO_HALF (resp. audio, spu, osd)can be used to wait for the microcode FIFO to be half full.See the details in playasync.c about this (change SUBPACKET value).Remark 3The ACQUIRE()/RELEASE() logics is reset at each mmap() operation to preventfailure of an application from making the kernel module driver unusable.Remark 4Using the transfer without copy requires the application to fill the data directlyin mapped dma buffers. This causes code like: repacketization, audio streamsoftware decoding, audio resampling, difficult to write (see mixing modes paragraph).Remark 5To graph the results of playasync.c, run:$ ./playasync 1 m2v /my/file.m2v >data$ cat data |awk '{print $2" "$10}' >data.bytes$ cat data |awk '{print $2" "$18}' >data.entries$ gnuplot> plot 'data.bytes' with lines, 'data.entries' with linesWith copy---------The reference application is playvideo.cIn this model, the kernel allocates one hidden dma buffer per stream (video, audio, spu and osd) when running insmod. These buffer are in no way related to thedma buffers of the `without copy' model (and cannot be mmap()'d in userland).-------------------------------------------------------------- (see realmagichwl.h)#define REALMAGICHWL_VIDEODMASIZE 64*1024// the audio DMA buf may be used to implement a sound driver#define REALMAGICHWL_FRAGMENTSIZE 1024#define REALMAGICHWL_AUDIOFRAGMENTCOUNT 64#define REALMAGICHWL_AUDIODMASIZE (REALMAGICHWL_AUDIOFRAGMENTCOUNT*REALMAGICHWL_FRAGMENTSIZE)#define REALMAGICHWL_SPUDMASIZE 16*1024#define REALMAGICHWL_OSDDMASIZE 64*1024-----------------------------------------------------------------------------------These values are suitable for most applications (and Linux will not be able to allocateeasily more than 128KBytes at once when memory is scarce).Data to be sent can be allocated by user at any place (even on stack) and the useris guaranteed that, when RUA_DECODER_FEEDME() succeeds, the data has been copied in theappropriate location and can be freed immediately.Obviously you cannot send at once a packet larger than the sizes given above.The happenings REALMAGICHWL_HAPPENING_DECODER_VIDEO_THRESHOLD (resp. ...AUDIO...) used to be the way to wait for data to be accepted again; unfortunately these reflect theinternal microcode waterlevel (<2/3) not directly related to the room in FIFO entries or theroom left in the considered hidden dma buffer.We advise now to use: REALMAGICHWL_HAPPENING_DECODER_VIDEODMA_HALFhappening (resp. audio, spu, osd) which guarantees that the user willbe able to RUA_DECODER_FEEDME() successfully one buffer under the following condition:___ its size must not exceed REALMAGICHWL_VIDEODMASIZE/4 ___ (resp. audio, spu, osd).Mixing modes------------RUA supports mixing packets originated from dma buffers (without copy mode)and any other copied data as a normal means of use.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -