DSP

基于Gstreamer的TI DSP视频处理框架

2019-07-13 12:45发布

本文主要介绍在TI的DSP平台,尤其是非对称多核的Davinci和OMAP平台上基于Gstreamer的多媒体处理框架,对GPP+DSP+视频协处理器VICP的多核架构,Gstreamer的插件设计来进行音视频codec的任务分工和调度。数字信号处理器DSP能提供出 {MOD}的多媒体功能。通常情况下仅需要通用CPU(General-Purpose Processor, GPP)的40%~50%的周期数来完成一个codec,同时DSP相比ASIC又能提供更好的灵活性和可配置型。但是到目前为止,DSP程序员还是需要相当的学习来掌握数字视频应用中的DSP编程,为适应日益广泛的DSP应用降低学习DSP编程的时间风险,APIs可以让DSP像通用处理器GPP那样可以直接构建应用程序。 通常都是运行于GPP的Linux操作系统的开源的多媒体框架就是这种桥接的APIs。Video codec的复杂计算可以让DSP来完成,包装成API直接应用。这种方式将DSP编程抽象化成上层的API供应用程序调用,这种简便的调用将可以充分利用开源的框架提供的众多功能,从而加速视频产品的上市时间。 Choices 
选择合适的硬件平台实现自己视频的传输和存储、浏览和编辑,开发人员通常有很多的选择。ASICs通常因其硬件的专门定制化而具有最高的性能和极低的功耗,但是却往往ASICs的实现无法继承,每一个应用的开发都是重新开始的。同样,如果需要改变功能,如修改视频编码标准,则必须重新选择ASIC芯片。相反,对于GPP处理器而言,其可配置性以及重新编程以满足更新的需求极为便利。但是其处理运算密集型的视频算法的能力较弱,如GPPs实现乘法运算需要多次的移位和相加运算。DSP则具有GPPs和ASIC的优势,一方面是针对信号处理的指令加强(如单指令的乘法指令),一方面是依然可编程,很容易适应算法和标准的定制和修改。而高性能的DSP如TI的C64x、C64x+系列的则可以在一个周期内的各个功能单元并行完成多达8条指令。这种高性能很容易让视频压缩标准从MPEG-2升级到H.264,通过软件的升级来适应更高的压缩效率的需求。但DSP实现的缺点在于需要开发者有一定的相关知识,熟悉DSP的结构和编程方式。
Integration challenges 
视频系统的开发者同样需要面临集成的挑战,视频应用可以包含多个编码器,多个解码器,多个其他的预处理和后处理算法的软件功能单元。这些功能单元集成在一起成一个可执行包,根据需求来启动某个软件功能单元以完成应用需求。因此调和各个功能单元以无冲突的工作将是一件相当有风险的事。同时专门投入人力来手动完成系统集成也是很消耗资源的,本来这些人力资源可以投入到其他附加功能和创新功能的开发的。
很多开发者采用开源软件来构建软件。一个通常的做法就是从开源软件来得到系统的很大一部分,然后根据硬件平台和应用需求加入自己的代码。这样结合开源软件和自己开发的软件就可以构建自己的产品了。 New API 
考虑到以上的问题,TI开发了让DSPs来直接利用开源的多媒体框架,如Gstreamer的API。这些API能让多媒体集成程序员采用类似的框架直接调用DSP的codec engine,这样集成就不要非常了解DSP的编程方法了,从而可以跟ARM/Linux的编程方式相同,同时利用了DSP的对codec的加速处理特性,又能像一般的GPP编程一样来构架媒体程序。基于DSP的这些接口可以采用TI提供的类似Gstreamer的plug-in插件。
Gstreamer是一种媒体处理库,是一种基于从输入到输出的管道流处理的抽象模型,因为其能简单的编程抽象处理众多类型的媒体而在数字视频和音乐播放器等领域获得了广泛的应用。Gstreamer让支持若干种格式和网络协议的通用视频和音频播放器变得容易实现。通常的处理并不是由Gstreamer的core来完成,而是通过各种plug-in。GStreamer的功能主要和plug-in的注册和加载相关,而且也提供实现基本功能的类。 GStreamer filters 
源过滤器(Source filters)是处理源媒体数据的,他们将从磁盘上的文件,CD/DVD上的源文件或者其他的如网络和采集设备等硬件设备采集到得源数据。一些源过滤器是直接将原始数据传给一个parser或者splitter解析器,而其他的一些源过滤器会自己来做解析。变换滤波器接受原始数据或者部分处理的数据,然后处理这些数据并输出。
有很多类型的变换过滤器,包括parser,将原始数据分割成采样点或者帧;compressor和decompressor以及format converter。渲染过滤器则接受完全处理好的,然后输出给monitor监视器或者speaker扬声器。还有一类是"file writer"过滤器,是将数据保存到磁盘或者其他的持久存储单元,还有就是将数据进行传输的网络传输过滤器。 数据处理都是在plug-in_chain()和plug-in_loop函数内完成的。这些函数或是一些简单如scale的操作或是复杂如一个MP3解码的操作。当数据处理完毕,通过GStreamer的一个gst_pad_push()函数将原数据送出到下一个元素单元,如管道。 GStreamer buffers Buffers是GStreamer的数据传输的基本单元。GstBuffer类型提供了定义一定区域的momory来作为stream的一部分。通过GstBuffer的结构体来表示数据和其他操作系统下(如Microsoft DirectShow)的多媒体框架的实现方式完全相同。让一个更小的区域的缓冲成为自有的buffer以保证内存空间不会过早的释放的Subbuffers也是支持的。 通常使用gst_buffer_new()函数来创建Buffers。一个buffer创建后,需要分配内存并设置buffer大小。下面的例子将创建一个buffer来保存一定宽度和高度的视频帧数据。
Addressing
Davinci处理器DM644x上的ARM926的core的MMU单元 可以进行虚拟和物理地址(virtual/physical)的转换。但是C64x+的DSP core只能采用物理地址,因而提供给DSP的输入和输出的buffer必须是物理连续的内存空间。 虚拟到物理内存的地址转换是由codec engine来完成的,物理连续的内存空间可以通过复用一些driver分配的空间来实现,采用Linux系统中的dma_alloc_coherent()在kernel空间来分配连续的空间。TI开发CMEM库也可以在用户空间的应用程序进行连续的物理空间的分配。
考虑用之前提到的CMEM的驱动进行物理连续空间的输出buffer的分配时,codec engine会解码当前帧,并把解码的帧数据保存到输出缓冲区。指向输出缓冲区的指针会通过GstBuffer传递给fbvideosink,videosink会用memcpy来把解码数据拷贝到显示的帧缓冲区。由于memcpy对于数据量巨大的视频处理而言是需要相当的处理资源的,将加大ARM和DDR的负荷,增加功率消耗。使用memcpy来处理较小分辨率的video还是可行的,但是当分辨率达到D1时,这种处理方式效率太低。更为有效的方式是复用driver里分配的物理连续的buffer,然后把指针在codec engine和videosink的plug-in间来回传递。而GStreamer则提供这种类型的API来完成指针的来回传递。
这种API是用gst_buffer_new()创建新buffer的替代方法,首先调用的gst_pad_alloc_buffer()函数已经确知源衬垫需要推得数据,然后提供指定的buffer供调用元素来工作,从而减少memcpy。 视频解码plug-in是通过codec engine API调用DSP来加速的变换过滤器。该过滤器将采用从渲染器获取的buffer指针作为输出buffer地址,然后开始解码。解码结束后,输出buffer就被push出去给渲染plug-in。此时解码的图像已经放在driver分配的内存空间,所以就不用memcpy了,渲染器只需要切换当前显示帧buffer为指定的现实图像即可。 AV sync processing 
AV同步(Audio/video synchronization)处理在回放时需要考虑3种决策。
? 重复一桢,当前显示的间隔小于从流处理中得到的时间标签时采用该种策略; ? 显示一桢,当前从流接受的时间介于某个最小和最大的边界值之间时采用的策略。 ? 跳过当前帧,当接收的帧两帧或者更多帧落后于显示帧时,跳过以让后续帧尽快的赶上显示。 此外,所有管道里的元素都可以采用一个通用时钟来帮助决策。所有这些音视频的决策都包含在Gstreamer的core库里。很多的AV同步的复杂算法对用户而言都是抽象的,只需要关心API接口,不用理会具体实现。 Interface developed as plug-in 
TI开发的GStreamer变换过滤器plug-in可以用DSP来完成复杂的编解码操作,同时用ARM上跑的Linux系统来完成集成封装。TI还提供Linux系统上的负荷标准驱动接口规范的驱动,以及codec engine的API来抽象复杂的的DSP编程算法。这些由硬件加速器实现的API已经经过了硬件的优化,效率很高,如果切换到另外一个平台,只需要替换新的driver来驱动复杂的信号处理算法,而不需要改变应用程序。这种实现方式降低了成本,加速了视频开发的进程。
硬件设备的计算资源是毋庸汇编编程的最有效的实现,包括复杂的DSP资源利用和硬件加速器,使用EDMA来有效的实现外设和Memory间高效的数据传递等。而Gstreamer这种开源的多媒体框架已经在各种平台上得到广泛应用,能够通过TI提供的标准API访问DSP的资源,从而集成时可以利用TI的DSP处理能力,同事还能共享GPP的应用程序开发。编解码等复杂处理可以与GStreamer的其他plug-in一起在应用程序里,框架性的处理让需要手工编程实现的多硬件资源共用成为简单的应用程序构建。   Reference: http://www.eetimes.com/design/signal-processing-dsp/4004620/DSP-video-processing-via-open-sourceAPIs http://www.gstreamer.net/ http://zh.wikipedia.org/zh/GStreamer http://en.wikipedia.org/wiki/GStreamer 本文主要介绍在TI的DSP平台,尤其是非对称多核的Davinci和OMAP平台上基于Gstreamer的多媒体处理框架,对GPP+DSP+视频协处理器VICP的多核架构,Gstreamer的插件设计来进行音视频codec的任务分工和调度。