« 上一篇下一篇 »

ffmpeg(neon优化)性能的一些总结

近段时间做的车联网项目一直在nexus5手机上做测试,对于手机屏幕投射到车机大屏幕这项技术而言,其实本质上可以看做是一个精简版的直播技术的实现,和当下热门的直播技术本质上是相似的,只是这里直播的是手机屏幕的内容而已。这块的流程简单来说就是在手机端通过android系统内部的接口获取手机屏幕一帧一帧的原始RGBA图像数据,然后通过sws_scale进行缩放并且转换为YUV420格式,然后利用ffmpeg-x264将其编码为h264包后再通过网络传送给车机端,车机端通过网络获取h264包后,利用ffmpeg-x264将其解码成YUV420后利用SDL显示出来。流程如下:


内部接口获取屏幕内容(手机端)==>sws_scale进行缩放和格式转换(手机端)==>ffmpeg-x264进行编码(手机端)==>网络传输==>ffmpeg-x264进行解码(车机端)==>SDL显示(车机端


一般来说视频都是25帧每秒,也就是说处理一帧的数据要控制在40毫秒之内,要达到这个目标还是要动点脑筋的,首先就是ffmpeg-x264编译的时候一定要启用neon优化,启用neon优化后在我的nexus5手机上用sws_scale将1080*1920的RGBA原始数据转换成486*864的YUV420格式的帧数据基本可以控制在平均30多毫秒的样子。在这个过程中我也尝试过使用另外一个库Ne10,它是ARM官方发布的一个开源库,里面提供了大量的浮点运算、矢量计算,和矩阵操作函数,可以快速创建Neon应用。利用其中的图像处理函数ne10_img_resize_bilinear_rgba_neon进行RGBA的缩放性能确实不错,可以控制在平均20多毫秒的样子,可惜它只能缩放,我还是需要再次将缩放后的RGBA图像转换成YUV420格式,所以只能果断放弃。接着就是h264编码,可以使用av_opt_set设置preset参数,可选的参数有slow,fast,veryfast,superfast,ultrafast等等这些,它们对编码的速度有很大影响,当然编码质量也会有影响,这些参数最终会传给x264库,我用superfast选项,利用neon优化过的x264库对486*864大小的YUV420格式的帧进行编码,编码成I帧的时间都能控制在40毫秒之内,编码成B帧和P帧的时间更是要短得多。由此可见几个关键步骤都能够控制在40毫秒之内,但是如果把这几个步骤串行起来后,时间就大大超过40毫秒了,所以我们还得利用操作系统多线程,CPU多核等特性,再加上队列的支持,让这些步骤并行化,这样整体处理一帧的时间就能控制在40毫秒内了。这里主要说的是手机端的编码部分,而对于车机端的解码部分基本相似,这里不再复述。