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轉換也未嘗不可。