這個公眾號會路線圖 式的遍歷分享音視頻技術(shù):音視頻基礎(chǔ) → 音視頻工具 → 音視頻工程示例 → 音視頻工業(yè)實戰(zhàn)。
隨著相機采集越來越多的與濾鏡拷橘、美顏靡砌、特效等前處理流程結(jié)合识藤,關(guān)注采集預覽的性能變得十分重要窖杀。采集預覽階段表示打開相機肺孵,但是還沒開始進行直播推流或者視頻錄制的階段,但這時候一般也開始進行濾鏡、美顏害淤、特效前處理了。在這個階段我們可以關(guān)注以下性能指標:
- 相機打開成功率拓售,相機成功打開沒有發(fā)生錯誤的比例窥摄。
- 相機打開速度相關(guān):
- 相機打開平均時長,從相機打開到第一幀采集到的圖像被預覽模塊渲染出來的平均時長础淤。
- 相機打開秒開率崭放,從相機打開到第一幀采集到的圖像被預覽模塊渲染出來的時長小于 1s 的比例。
- 采集預覽流暢度相關(guān):
- 預覽平均采集幀率值骇,預覽階段相機采集的幀率莹菱。
- 預覽平均識別幀率,預覽階段相機采集后經(jīng)過前處理后的幀率吱瘩。
- 預覽平均渲染幀率,預覽階段前處理完成后預覽渲染幀率迹缀。
此外使碾,我們還需要關(guān)注:采集畫面質(zhì)量、采集內(nèi)存等指標的優(yōu)化祝懂。
1票摇、相機打開成功率優(yōu)化
1.1、權(quán)限檢測與引導
手機設(shè)備上的應用要打開相機是需要向用戶申請權(quán)限的砚蓬,所以優(yōu)化權(quán)限申請的交互及文案提升權(quán)限通過率是優(yōu)化相機打開成功率的一個方案矢门。
這里有幾個建議:
- 1)只在確實需要使用相機的場景才向用戶申請相機權(quán)限;
- 2)提前向用戶說明申請相機權(quán)限對后續(xù)功能的必要性灰蛙;
- 3)正式申請權(quán)限前先測試用戶意愿祟剔。在有些手機系統(tǒng)的設(shè)計中,如果用戶拒絕了你的權(quán)限申請摩梧,那么下一次需要到手機設(shè)置中找到對應 App 的隱私權(quán)限選項才能打開權(quán)限物延,這里的路徑很深。因此仅父,可以在真正申請權(quán)限前叛薯,彈出選擇框讓用戶選擇是否同意授予權(quán)限,如果用戶同意才正式彈出權(quán)限申請窗口來申請權(quán)限笙纤,避免因為用戶此次拒絕了權(quán)限申請而加大了后續(xù)獲取權(quán)限的難度和成本耗溜。
1.2、錯誤重試與監(jiān)測
如果確實遇到相機打開報錯省容,可以重試相機打開流程抖拴。
另外,需要統(tǒng)計相機打開錯誤的細分錯誤碼蓉冈,這樣就能更好的定位相機打開失敗的原因進行針對性的優(yōu)化城舞。
2轩触、相機打開速度優(yōu)化
2.1、優(yōu)先使用 CPU 資源
優(yōu)化相機打開速度家夺,可以從業(yè)務(wù)層進行處理脱柱,優(yōu)先將 CPU 資源讓給相機,相機打開后回調(diào)給業(yè)務(wù)相機首幀已出的事件拉馋,這樣業(yè)務(wù)收到該事件后再進行其它初始化榨为,體驗會得到很大提升。
2.2随闺、異步初始化非必要組件
通常相機會與特效等 SDK 混合使用,可以子線程異步加載特效組件蔓腐,首幀可以無特效立即展示出來矩乐,等檢測特效加載好后再加入效果即可。
2.3回论、首幀占位體驗優(yōu)化
第一幀展示前可以使用上一次關(guān)閉高斯模糊圖來占位散罕,這樣體驗比純黑色效果好很多,可參考微信朋友圈相機傀蓉。
3欧漱、采集預覽流暢度優(yōu)化
3.1、線程模型優(yōu)化
把采集和視頻特效放在同一個線程葬燎,隨著特效功能越來越強误甚,計算越來越重,會影響到最終的輸出幀率谱净。要優(yōu)化可以改為多線程的方式窑邦,這里有下面幾點需要注意:
1)使可并發(fā)的任務(wù)跑在不同的線程上:
- 采集線程:使用系統(tǒng)相機能力實現(xiàn)圖像采集;
- CPU 處理線程:跑一些 AI 模型任務(wù)岳遥;
- GPU 處理線程:跑一些圖像處理任務(wù)奕翔。
2)使用緩沖區(qū)組合生產(chǎn)消費者模型,各個模塊可以并行浩蓉,而且性能兼容性更好:
- 線程 1:采集 → buffer 1 → 線程 2:圖像處理 → buffer 2 → 主線程:渲染
這樣一來派继,在采集后如果要繼續(xù)做其他任務(wù)(比如編碼、發(fā)送網(wǎng)絡(luò)等)也能比較方便的接入捻艳。
3.2驾窟、采集與前處理數(shù)據(jù)交互優(yōu)化
采集和前處理(AI 模型、圖像處理认轨、特效等)模塊交互時绅络,可以做下面幾項優(yōu)化:
- 采集到圖像處理進行圖像下采樣。有時候我們采集時需要較高的分辨率,但是在算法處理時則不需要恩急,這時候采集完直接下采樣交給后續(xù)的圖像處理鏈路杉畜,可以降低數(shù)據(jù)量,優(yōu)化性能衷恭。
- 圖像處理鏈路對齊分辨率此叠,防止多次采樣消耗性能。圖像處理鏈路也不光是下采樣就完了随珠,因為整個圖像處理鏈路可能涉及不同的節(jié)點(比如人臉識別模塊灭袁、降噪模塊、美顏模塊)窗看,如果這幾個節(jié)點對應的算法輸入分辨率不一致茸歧,那就需要一路上做多次圖像上采樣或下采樣,這樣就帶來了額外的性能開銷显沈。如果在數(shù)據(jù)鏈路設(shè)計之初软瞎,各個模塊就能對齊分辨率,就節(jié)省了反復上下采樣的消耗拉讯。
- 圖像處理鏈路對齊顏色空間铜涉,防止顏色空間轉(zhuǎn)換消耗性能。同樣的遂唧,不同的節(jié)點的算法模型如果使用不同的顏色空間,一路下來就會涉及顏色格式的轉(zhuǎn)換吊奢,這樣也會帶來更多的性能開銷盖彭。
3.3、減少 CPU 與 GPU 的數(shù)據(jù)拷貝
GPU 和 CPU 要盡量少做數(shù)據(jù)拷貝页滚,性能比較差召边。可以使用系統(tǒng)能力來實現(xiàn) GPU 和 CPU 的內(nèi)存共享來做相關(guān)的優(yōu)化裹驰。
比如在 iOS 上隧熙,使用設(shè)置了 kCVPixelBufferIOSurfacePropertiesKey
屬性的 CVPixelBufferRef 是可以支持 GPU 和 CPU 共享內(nèi)存的。從相機采集出來的幻林、從 VideoToolbox 解碼出來的 CVPixelBufferRef 都具有這個屬性贞盯,所以通常來講使用系統(tǒng)的 API 時,你并不太需要操心這個問題沪饺。
如果你要自己創(chuàng)建一個圖像來進行渲染躏敢,還希望能讀出其數(shù)據(jù)做其他處理,并且希望支持 GPU 和 CPU 共享內(nèi)存整葡,可以參考下面這篇文章:Rendering to a texture with iOS 5 texture cache api[1]
3.4件余、不同設(shè)備智能選擇分辨率和幀率
通常低端機效果較多情況下選擇 1080P + 30FPS 會比較卡,影響用戶體驗,如何選擇合適的分辨率和幀率則尤為重要啼器。
- 服務(wù)器大數(shù)據(jù)收集每個機型的平均幀率與分辨率旬渠,對于不滿足幀率閥值則需要調(diào)整分辨率或幀率,也可以降低某些特效復雜度來提高幀率端壳;
- 針對于機型緯度種類會非常多告丢,也可以參考使用芯片等其它維度進行設(shè)備打分,通過打分方式對于不同設(shè)備選擇不同參數(shù)更哄。
4芋齿、采集畫面質(zhì)量優(yōu)化
畫面采集質(zhì)量,比如清晰度成翩、亮度等指標對于最終視頻觀看的體驗尤為重要觅捆,可通過以下幾點嘗試提高畫質(zhì):
4.1、對焦優(yōu)化
可智能選擇人臉自動對焦或者手動對焦麻敌,防止曝光不合理影響畫質(zhì)栅炒。下面的對焦策略,可以參考:
- 手動對焦:
- 用戶點擊哪里就對焦哪里术羔。
- 自動對焦:
- 基于系統(tǒng)能力在識別場景發(fā)生變化后赢赊,進行一次中心對焦。比如在 iOS 系統(tǒng)中级历,可以監(jiān)聽 AVCaptureDeviceSubjectAreaDidChangeNotification 系統(tǒng)通知释移,檢測到場景變化時觸發(fā)對焦。
- 如果有識別到畫面從無人臉到有人臉時寥殖,做一次人臉對焦(這里是只做一次人臉對焦玩讳,不能一直跟著人臉對焦,這樣可以防止用戶不想對焦人臉的場景:在有人臉時嚼贡,點擊了其他地方進行手動對焦)熏纯。
- 人臉對焦時,一般對焦兩眼中間的點位效果比較好粤策。比如在 iOS 系統(tǒng)樟澜,可以使用 AVCaptureMetadataOutput 設(shè)置 AVMetadataObjectTypeFace,但缺點是僅能獲取到人臉框叮盘,無法得到精準點秩贰,可以選擇對焦人臉框中心點。如果能使用其他人臉識別 SDK 來識別到精準點熊户,可以對焦到兩眼中心效果會更好萍膛,比如常取 43 號點位。
- 手動對焦后嚷堡,在滿足這些條件時會切換到自動對焦:
- 前后攝像頭切換蝗罗。
- 場景發(fā)生較大切換艇棕。比如,相機位移或晃動較大串塑,外部光線敏感度變化較大等沼琉。
- 畫面中從無人臉變?yōu)橛腥四槨?/li>
4.2、攝像頭模糊優(yōu)化
很多手機在使用中可能會出現(xiàn)鏡頭被弄臟的情況桩匪,這時候采集處理的畫面質(zhì)量自然就比較模糊了打瘪,針對這種情況可通過算法檢測預覽畫面是否模糊,并提示用戶清潔一下攝像頭來解決清晰度的問題傻昙。
4.3闺骚、畫質(zhì)增強優(yōu)化
對于采集后的圖像還可以通過算法進行畫質(zhì)增強。
音視頻知識圖譜 2022.09中就介紹了部分圖像降噪和增強相關(guān)的算法分類妆档,這里就不深入探討了僻爽。
5、采集內(nèi)存優(yōu)化
優(yōu)化相機內(nèi)存占用大小贾惦,有利于減少內(nèi)存 OOM
問題導致的崩潰胸梆。在不同的平臺,可以選擇恰當?shù)牟杉瘮?shù)據(jù)輸出格式來優(yōu)化內(nèi)存使用:
1)iOS 采集數(shù)據(jù)輸出格式
輸出格式可配置為 BGRA
& YUV
须板,盡量設(shè)置為 YUV
數(shù)據(jù)格式碰镜,可以減少 width * height * 2.5
數(shù)據(jù)大小。
1)例如
720 * 1280
分辨率习瑰,單張圖片BGRA
占用720 * 1280 * 4 = 3.5M
绪颖,YUV
占用720 * 1280 * 1.5 = 1.3M
。2)由于系統(tǒng)底層存儲了
CVPixelBufferPool
隊列甜奄,使用隊列的好處是當外層鎖住 CVPixelBufferA菠发,底層則直接使用 CVPixelBufferB,有利于提高多線程性能贺嫂,如果全部都鎖住了,那相機將不會再吐數(shù)據(jù)雁乡。實測隊列大小為13
第喳,所以YUV
數(shù)據(jù)格式相對于BGRA
節(jié)約共(3.5 M - 1.3M) * 13 = 28.6M
。- 因為渲染紋理需要
BGRA
踱稍,所以需要通過 OpenGLES 將YUV
數(shù)據(jù)轉(zhuǎn)換為 BGRA 紋理即可曲饱,開銷非常小。另一個好處是很多算法輸入也都是YUV
數(shù)據(jù)格式珠月。
- 因為渲染紋理需要
2)Android 采集數(shù)據(jù)輸出格式
安卓因為支持 Camera1 & Camera2 兩種模式扩淀,通常根據(jù)線上大數(shù)據(jù)決定當前設(shè)備啟用哪種模式。
- 1)Camera1 支持輸出
YUV
或者SurfaceTexture
啤挎,如果需要算法識別則輸出YUV
驻谆,不需要則直接輸出SurfaceTexture
來提高性能卵凑。 - 2)如果輸出
YUV
數(shù)據(jù)格式,通常需要每一幀進行旋轉(zhuǎn)胜臊,做圖像的裁剪勺卢、縮放、旋轉(zhuǎn)象对、尺寸變化時要注意優(yōu)化性能黑忱。可以使用 libyuv 來做常規(guī)的圖像處理勒魔,一些 libyuv 版本甚至做過匯編級別的優(yōu)化來提升圖像處理的性能甫煞。
參考資料
[1]
Rendering to a texture with iOS 5 texture cache api: allmybrain.com/2011/12/08/…
- 完 -
推薦閱讀