最初在項目中做實時視頻流的時候,采用的方案是蝶防,設置Camera Preview格式是NV21偎箫,最終MediaCodec需要的格式是I420,由于之前對YUV一無所知缰雇,所以一些旋轉(zhuǎn)算法也是在網(wǎng)上淘的入偷,導致有部分是在NV21的時候進行旋轉(zhuǎn),有部分則是在I420的時候進行旋轉(zhuǎn)寓涨,最終還是實現(xiàn)了功能盯串。
最近時間比較多氯檐,也要在視頻流上增加水印戒良,決定對這部分性能進行優(yōu)化,所以著重學習了解了一下YUV格式冠摄。
在Android文檔糯崎,Camera里面有這樣一句話
If this is never called, the default format will beNV21, which uses the NV21 encoding format.
UsegetSupportedPreviewFormats()to get a list of the available preview formats.
It is strongly recommended that eitherNV21orYV12is used, since they are supported by all camera devices.
在Camera中推薦使用NV21和YV12,因為這兩種格式支持所有的相機設備河泳。
但是在Camera2中沃呢,推薦使用的格式則是YUV_420_888。
總的來說拆挥,在Android里面YUV用得比較多的應該是I420, YV12, NV12和NV21薄霜,其中I420和YV12都是Y420P某抓,NV12和NV21都是Y420SP。
這幾種格式相同點和區(qū)別呢可以這樣看:
YUV420SP格式
YUV420SP:圖中Y1,Y2,Y9,Y10共用一對UV:U1和V1
YUV420P格式
YUV420P:圖中Y1,Y2,Y9,Y10共用一對UV:U1和V1
I420: YYYYYYYY UU VV? ? =>YUV420P
YV12: YYYYYYYY VV UU? ? =>YUV420P
NV12: YYYYYYYY UVUV? ?? =>YUV420SP
NV21: YYYYYYYY VUVU? ?? =>YUV420SP
他們的共同點是一個Y代表一個像素點惰瓜,Y的大小就等于width * height否副,由于它們都說420格式,所以UV總長位width * height / 2崎坊,其中U和V各占一般長度备禀。所以在代碼中新建一個byte[]的時候長度為 width * height * 3 / 2。
YV12:
YV12 is a 4:2:0 YCrCb planar format comprised of a WxH Y plane followed by (W/2) x (H/2) Cr and Cb planes.
所以我針對之前項目的改進方案就是奈揍,預覽輸出使用YV12格式曲尸,通過轉(zhuǎn)換和旋轉(zhuǎn)轉(zhuǎn)成I420格式。
因為YV12和I420的結(jié)構(gòu)很相似男翰,只需要調(diào)換UV分量的位置即可另患,更方便在同一個循環(huán)中同時進行旋轉(zhuǎn)和轉(zhuǎn)換,相比之前的方案旋轉(zhuǎn)和轉(zhuǎn)換是兩個循環(huán)蛾绎,這樣效率更高柴淘。
最終實測,各個方向分別統(tǒng)計了幾百幀的數(shù)據(jù)求算術平均值秘通,YV12->I420比NV21->I420的旋轉(zhuǎn)+轉(zhuǎn)換为严,每幀少花3ms左右,不管各位看管覺得怎么樣肺稀,對我來說是個不錯的鼓舞第股。
我的YV12轉(zhuǎn)NV21的代碼,雖然是Java層的话原,速度還不錯夕吻,每幀耗時小于1ms
下一步優(yōu)化的目標就是把耗時算法放到JNI層去做。
參考:blog.csdn.net/jefry_xdz/article/details/7931018
www.cnblogs.com/samaritan/p/YUV.html
作者:黃河遠去樓依在
鏈接:http://www.reibang.com/p/102b8b0797b7
來源:簡書
著作權歸作者所有繁仁。商業(yè)轉(zhuǎn)載請聯(lián)系作者獲得授權涉馅,非商業(yè)轉(zhuǎn)載請注明出處。