Android设备中几种YUV420p转rgb视频帧方法效率比较
编者:李国帅
qq:9611153 微信lgs9611153
时间:2020-03-30
背景原因:
从android的camera之中获取视频帧,或者从第三方ipc比如海康大华的sdk api获取的视频帧,往往都是yuv格式的,比如yv12,i420。
这些视频帧要想显示到android的view/surface中,需要把yuv格式转换为rgb格式,通过view的canvas绘制到界面上。
正在上传…重新上传取消
中间碰到了这么个问题:因为java语言自身的效率问题,要处理高频率,大数据的数据转换往往效率很低。普通的操作很容易造成视频回显的阻塞,影响用户使用。
YUV420p转rgb通常有几个方法:
(华为平板2g内存下)
1、常见的就是使用YuvImage间接实现,但是这种方案效率很低,通常一帧640*480的转换需要40~50毫秒。
此方法仅可以转NV21和YUY2,还需要从先转换为NV21.
2、据说使用 renderscript.ScriptIntrinsicYuvToRGB效率很高,内部原理不明,实测大概20毫秒左右。不过问题是只能从nv12转rgb,要添加从yv12转nv12的操作。
3、yv12和rgb之间的鸿沟并不是很深,并且可以直接使用代码实现转换。如果使用java代码直接转换,大约也就40毫秒。
4、当然了,如果能使用jni方法嵌入程序的c语言转换函数,效率会有所提高。记得以前总结过一篇《使用ffmpeg中的转换库进行颜色转换》,应该速度比renderscript快。
使用代码进行测试:
写一个程序,使用纯java代码测试,创建随机图像,对几种方法进行对比。
正在上传…重新上传取消
测试结果:
正在上传…重新上传取消
03-30 11:44:20.421 32436-32436/? D/MainActivity: YuvImage处理1帧耗时=82
03-30 11:44:20.471 32436-32436/? D/MainActivity: 直接转换处理1帧耗时=49
03-30 11:44:20.491 32436-32436/? D/MainActivity: 使用renderscript.ScriptIntrinsicYuvToRGB处理1帧耗时=20
03-30 11:44:21.511 32436-32436/? D/MainActivity: YuvImage处理1帧耗时=85
03-30 11:44:21.561 32436-32436/? D/MainActivity: 直接转换处理1帧耗时=47
03-30 11:44:21.581 32436-32436/? D/MainActivity: 使用renderscript.ScriptIntrinsicYuvToRGB处理1帧耗时=23
正在上传…重新上传取消
总结:
方法没有好坏,使用在恰当的地方就是好方法。追求都是要付出成本的,就看值不值得了。
如果设定帧率在10以下,使用yuv转换也未尝不可。