虽然还有一年才毕业但毕业设计我已经作完了,大约用了3个月时间。我是个急性子并且对感兴趣的知识有非常强烈的学习欲,另外总想多写一些其他的知识,像
ARM,linux,网络我都很感兴趣。这学期开始选题的时候我鬼使神差的选择了视频编码,题目是基于DM642的H.264视频编码器实现与优化,开题
答辩的时候所长说重点应该放在实现和应用上,一般公司优化都是很多人去做的。做着做着我又对网络感兴趣索性就加了网络部分,所以到最后基本上成为网络摄像
头的雏形。
它的基本过程是采集摄像头视频(YUV4:2:2),转换成YUV4:2:0,采用H
.264编码,PC机TELNET到DSP,发送命令,就可以接收到DSP传来的码流,最后解码并显示。视频大小为QCIF,UDP协议,DHCP动态获
得IP,PC端主程序解码,另外建立两个线程分别接受码流和显示图像。DSP采用DSP/BIOS系统框架,初始化网络和摄像头驱动之后就等待PC发命
令。
对DM642编程有点复杂,刚开始看例程无从下手,虽说是C语言,可是一堆的驱动以及CSL、BSL都需要慢慢熟悉。摄像头驱动FVID使用还算可
以,FVID_alloc(),FVID_exchange()就基本能满足要求,加上一个while就构成主体循环。摄像头获得的YUV422转化为
YUV420,这里我没有采用标准的转换,我当初就理解为隔行保留就可以了,所以就用DAT_copy()复制亮度和DAT_copy2d()简单的从缓
冲区隔行复制 {MOD}度到预编码数据区。T264_encode()是编码程序,其主体函数从T264中以dependent project
加入到主project中,我将其中大约50个c子程序用线性汇编或者内连函数改写,可以达到17帧的编码速度,主观感觉编码之后的视频不卡。这里我不得
不说对编码程序的优化这一块,另起一段吧。
我主要的精力都放在优化上了,但感觉就像个无底洞一样,自己没有能力也不想花太多的时间在这上面,编码速度总是无法再有质的飞跃,当初从4帧提升到17帧
(对于highway.qcif这样的视频序列仿真甚至能达到21帧)着实把我高兴坏了,对EDMA和CACHE的利用和优化好像总是隔着一层纱,深深感
到自己能力有限没法体会精髓,我总想找个高手能指点我一下,一直不能如愿,哎,真是人生得一知己足矣,一个志同道合的人只能是靠缘分了,可遇而不可求
啊!50个子函数的改写也把我累坏了,想想那些个日子从早上8点到晚上11点都是在写汇编函数,还真有点怀念,看见速度一点一点地提高是我最大最大的欣
慰。把50个函数都写一遍后发现编码之后的图像发生严重失真,肯定是汇编指令用错了或者压根程序就让我编错了,我不得不重新检查每一个函数(当初我每一个
函数都会用一组数据分别测试原C函数和我改写的汇编程序是否能达到一样的结果,可还是大意了,有些程序虽然对大多数数据都能得到一样的结果,但有些"极
端"数据却不能达到一样的结果,这也是后来才慢慢体会到的,使用汇编指令要对移位,溢出等情况详加考虑,不然等着傻眼吧,像LDB和LDBU,ROTL和
SHL,SHR和SHRU等就是最容易用错的),即使这样这一遍过后图像还是有些失真,我又对一些函数排除检查,终于达到良好的效果,我很欣慰。
网络部分参看NDK开发文档,如果有WINDOWS下网络编程经验就可以很轻松的上手,我就是先看了WINDOWS下socket编程,编了几个TCP UDP的程序,然后就可以十分轻松的编程,难点是初始化和熟悉过程。
PC机的解码和显示程序是T264自带的,看懂了程序框架之后加入网络线程,从DSP接收码流然后解码显示,原始程序是从本地磁盘读文件解码显示。采用消
息驱动接收码流,线程间共享码流变量和一些同步变量,在这里又对volatile和extern以及WIN32编程有了进一步理解。
所有这一切的前提是要熟读H.264编码标准文档,几百页吧,以及看懂T264编码程序,我的编码程序都加上了注释,以后复习能更快上手。这其实是很费时间和精力的,但我乐在其中。