本文的copyright归
[email protected]所有,使用GPL发布,可以自由拷贝,转载。但转载请保持文档的完整性,注明原作者及原链接,严禁用于任何商业用途。
========================================================
本文讨论的是基于DVSDK3,硬件平台是ZMV6467。
DVSDK TI为达芬奇平台的开发者提供了一套完善的视频软件开发套件。DVSDK功能非常强大,它将很多视频编解码的细节都隐藏起来了,使用者只需要
关系应用就可以,但是DVSDK的强大又使得它变得异常的庞大,让使用者摸不着头脑,或者根本不知道怎样开始开发。接下来的TI DVSDK学习记录文章
将会一步步分析DVSDK,将我学习使用DVSDK进行开发的过程中碰到的问题或者相关的经验一一写出,文章中不会涉及到如何构建编译环境,如何编译
DVSDK的问题,如需了解这方面的问题可以参考TI官方文档或联系勤泽。
文章如有错误敬请提出。
以视频采集应用的开发过程,提出以下问题:
1.视频怎样来,来自哪里?
2.采集到视频数据要怎样处理?(显示/压缩/存放/发送)
3.视频数据怎样直接显示出来?
4.视频数据怎样压缩?
5.视频数据怎样存放?
6.视频数据如何发送?
下面就开始一一来解决这些问题:
先从硬件功能框图看一下视频的输入通道,红色框部分:
DM6467支持BT.656/BT.1120/RAW的数据输入,最高可以支持1080P30FPS,如果需要支持1080P60fps,可以使用1GHz版本的DM6467T。
1)模拟高清分量输入,经过视频解码器后输出符合BT.1120的数据,然后再通过VPIF接口进入CPU。
2)模拟标清信号输入,经过视频解码器后输出符合BT.656的数据,然后再通过VPIF接口进入CPU。
3)数字摄像头(eg.cmos),直接通过VPIF接口进入CPU。这里要注意,因为DM6467只支持YUVPSemi4:2:0格式的数据显示和编码(H.264),所以数字摄像头输出的YCBCR或RGB数据再
进入CPU后需要进行转换(颜色空间的问题,可以参考本博客前面的文章),这个转换可以通过ARM,也可以通过DSP来进行,勤泽的软件已经附带了一个DSP的转换核,
可以直接转换cmos的YCBCR数据进行显示和编码。
数据进入CPU后,接下来就是要获取数据了,这部分的只使用到ARM端。
数据流向:
[video decoder driver] ----> [vpif_caputre driver] ---->[V4L2 driver]--->[应用层]
这里我们先不去关心video decoder driver 和 vpif_caputre driver,因为这两个不影响我们分析DVSDK。
这里的V4L2 driver和我们平常使用的V4L2驱动没什么区别,就是提供了一些访问视频设备的接口,但是TI为了
简化对V4L2的操作,方便用户更快的编写出视频应用程序,所以他们在V4L2的基础上又封装了一层叫做DMAI的东西。DMAI是什么呢?
因为接下来会有更多的新名词冒出,所以这里我们先看一下DVSDK的一个简单的构成框图,这个框图在后面会不断扩大:
从框图可以看出DMAI将视频编解码器(CE)、内存管理(CMEM)和V4L2的访问操作都统一到一套接口上了,这样视频编解码应用程序的开发
者只需要关系数据的业务应用而不需要去理会逻辑层的东西。
但是作为底层的开发人员,我们还是有必要去看看DMAI到底是怎样和CE/V4L2/CMEM进行交互,并且把它们封装起来的,然后到最后再看怎样使
用DMAI进行应用程序的开发。
1.DMAI与VL42的交互(DMAI版本:2_20_00_15)。
在dmai_2_20_00_15/packages/ti/sdo/dmai/linux/dm6467目录下有一个Capture.c的文件,Capture.c包含了所有对V4L2的操作封装。现在来看一下
文件中的一个函数,这个函数用于创建一个 视频捕获设备的操作句柄。
View Code
从上面的代码可以看出,DMAI的函数将大量的对V4L2的控制操作都封装起来了,使用者只需要传入缓冲区列表和视频采集参数就可以创建一个视频采集设备。设备采集到
数据后,会将数据填充到使用者提供的缓冲区,使用者只需要取出相应的缓冲区就可以得到视频数据。在上面的函数中,调用了一个_Dmai_v4l2DriverAlloc()函数,这个函数
的作用是分配视频缓冲区,它最终是调用CMEM进行内存分配的,下面一起看看这个函数的具体实现。
2.DMAI与CMEM的交互。
查看dmai_2_20_00_15/packages/ti/sdo/dmai/linux/dm6467/_VideoBuf.c
_Dmai_v4l2DriverAlloc()
继续分析Buffer_create()函数
查看dmai_2_20_00_15/packages/ti/sdo/dmai/Buffer.c。
Buffer_create()
数据已经得到了,它们就放在通过CMEM创建的缓冲区里,那么验证或使用这些数据的一种最简单又有效的方式就是将它们直接
显示出来。再来看一下DVSDK的框图:
框图的两条红线表示数据的流向,需要将数据显示出来只需要两部,第一步创建V4L2的显示出输出设备,第二创建显示缓冲区并将采集到的数据放到缓冲区内。
创建V4L2的显示设备和创建VL42的采集设备很相似,请查看dmai_2_20_00_15/packages/ti/sdo/dmai/linux/dm6467/Display_v4l2.c
Display_v4l2_create()
创建显示设备不需要检查视频标准,因为输出的标准是有调用者决定的。
显示设备创建好了,那怎样将采集到的数据显示出来呢?TI提供了一个叫encode的demo程序,大家可以在dvsdk_demos_3_10_00_16中找到。
这个demo中很巧妙的将视频采集缓冲区和视频显示缓冲区管理起来,接下来一下分析一下。
因为单个显示缓冲和采集缓冲区的大小是一样的,所以可以直接进行交互。
下面截取demo中的代码片段,看一下这个缓冲区的交互的具体实现。
capture and display buffer
到此为止,已经可以知道了数据是从哪里来到哪里去了,但是数据来了,肯定没那么容易就放它走,下一章将会讲到将采集到的数据如何编码并且保存。再加点预告,后面会讲到将编码后的数据通过live555发送出去,实现rtsp视频服务器。