DSP

DM365 DMAI

2019-07-13 19:54发布

本文部分摘自:“基于TMS320DM365 多平台实时视频传输系统的设计与实现” 宋建勋,刘峰

DMAI(DaVinci Multimedia ApplicationInterface)是DSP提供给ARM端应用程序的调用接口,DMAI封装了底层的驱动,是操作系统和编解码引擎之上的应用接口,可以方便编写出可以在达芬奇平台上用的应。它通过一个抽象的Buffer对象相互交流,可以携带实际的数据(如:视频、音频、声音),能够知道编解码引擎或者linux驱动对数据进行的操作。
DMAI是所有模块的集合,应用程序可以挑选并使用某个或某些模块。由于DMAI也提供了源码,因此,也可以参考DMAI来了解如何使用某个具体的设备驱动来完成特定的任务。 用程序DSP也是依赖于DSPLINK的。DMAI中也提供了许多VISA (video, imaging, speech andaudio)编解码的实例。DMAI提供的是一种功能的抽象,而在具体实现上,不同硬件平台,不同系统是不一个样的。另外,由于DMAI是以源代码的形式提供的,所以可以用来参考完成一些别的任务,比如设备驱动。 DMAI的优势:
1. 移植和重用:例如TI GStreamer plugin就是基于DMAI,它可以方便的移植到其他的davinci平台。
2. 软件接口一致:
(1)对底层硬件加速部分抽象封装,使开发者不需要明白平台的特定实现
(2)支持所有的codec,使开发者不必明白xDM版本的细节与区别
(3)对显示的抽象(FBDEV和V4L2)
(4)管理底层细节与错误处理,DMAI有个显示模块可以用来查找底层DVSDK的错误 本项目所做的工作:
为了使用DMAI接口函数中的采集模块,这就需要将DMAI接口函数融合进整个软件框架,也就是说,在程序中能够正常使用DMAI接口函数。由于使用了DMAI的采集模块,因此原参考板中的CMOS输入的采集驱动就会和DMAI采集驱动以及程序冲突,这时就需要卸载掉CMOS原有的驱动,并修改其代码。在DMAI采集模块获取到图像后,还需要对该图像缓冲区的结构进行调整,使它能够适应整个系统中的缓冲区结构。最后,由于缓冲区做了很大的调整,因此连续内存设备驱动模块的配置也需要做调整才能正常启动程序。 一般来讲,嵌入式Linux系统的视频采集都是靠调用V4L2驱动来实现,V4L2是一套用于处理Linux上多媒体设备的标准应用程序接口,通过这些接口,可以对视频输入设备执行打开、读写、关闭等操作。TI在底层驱动的基础上对设备驱动接口进行了二次封装,抽象成几个DMAI接口。应用程序开发者只需要调用这几个DMAI接口,就可以轻松实现对底层设备的访问,而不用关注实现的具体细节问题,从而使开发者可以把主要精力放在对视频的处理和后续功能的扩展上。
使用DMAI接口的视频采集与编码模块的功能由两个线程来完成,分别是capture thread线程和videothread线程,在这两个线程中都使用了DMAI接口,很大程度上方便了程序的开发。
capture thread 线程和video thread线程的通信是通过FIFO机制来完成的,其底层是通过pipe()调用来实现。首先,capturethread线程通过Fifo_get()调用从videothread线程获取一个空闲的buffer,经过Capture_get()调用后,这个buffer中就保存有刚刚捕获到的一帧视频数据,然后通过Fifo_put()调用,将这个buffer发送给videothread线程进行H.264编码。相应的,在videothread线程中也需要使用Fifo_get(),Fifo_put()这两个接口。
视频采集与编码模块的流程如图2所示。

视频采集线程
使用DMAI后,视频采集线程的执行流程就变得非常简单,下面进行详细分析:
1)创建一个视频捕捉设备驱动的实例。这个操作是使用DMAI中的Capture_create()调用来完成的,通过分析Capture_create()的实现代码可以看到,对视频输入设备的操作也是通过V4L2驱动来完成的,使用底层接口open("/dev/video0",O_RDWR,0)打开视频输入设备,通过系统调用ioctl()来查询和设置设备属性。
2)进行视频采集。这个操作是通过DMAI中的Capture_get()调用来完成,这个函数的功能也是通过ioctl()hCapture->fd,VIDIOC_DQBUF,&v4l2buf)这个底层的函数调用来实现的。
3)关闭视频输入设备。这个操作是通过DMAI中的Capture_delete()调用来完成的。这个调用的具体操作是,首先释放掉创建设备实例时申请的内存,然后再调用fclose("/dev/video0")关闭视频设备。
视频编码线程
基于达芬奇平台的视频编解码是通过调用编解码引擎(Codec Engine)来实现的。通过这种机制,ARM端的程序就可以通过CodecEngine提供的VISA(Video,Image,Speech,Audio)API接口调用,可在DSP端执行编解码算法,DSP端专门负责各种算法的执行,并通过VISAAPI接口将算法执行的结果返回给ARM端的程序。视频编码线程的执行流程为:
1)打开编码器引擎。这个操作是通过CodecEngine提供的Engine_open()调用来完成,把DSP的可执行程序加载到DSP的内存,同时把DSP从复位状态释放。
2)创建H.264视频编码器。这个操作是通过CodecEngine提供的Venc1_create()调用来完成,在使用这个调
用时,需要同时传递视频编码器的参数信息,例如,编码器输入的图像大小、帧率、编码后的比特率等。
3)编码一帧视频数据。这个操作是通过Codec Engine提供的Venc1_process()调用来完成,把获取的一帧
视频数据传递给DSP,DSP端程序对其执行H.264编码后,再将编码后的数据返还给ARM端指定的buffer。
4)关闭H.264视频编码器和编码器引擎。这两个操作分别是通过Venc1_delete()调用和Engine_close()调
用来完成,执行这两个操作后,就会释放DSP资源,DSP重新进入复位状态。