For investors
股價:
5.36 美元 %For investors
股價:
5.36 美元 %認(rèn)真做教育 專心促就業(yè)
經(jīng)典必看android學(xué)習(xí)視頻,從入門到精通的android視頻下載!通往名企,從學(xué)習(xí)android視頻下載開始!達(dá)內(nèi)android培訓(xùn)技術(shù)專家總結(jié)了android下播放器視頻輸出方法總結(jié)。
在Android下輸出視頻畫面,有很多種方法,每個都有自己的特點(diǎn),比如將視頻數(shù)據(jù)送回到j(luò)ava層然后用lockCanvas畫出來這種方法的特點(diǎn)就是慢.
上面這個完全不值得提倡,視頻數(shù)據(jù)從native層傳到j(luò)ni層很耗時間.
開發(fā)基于ffmpeg的播放器時,可以使用ffmpeg的各種軟解碼器,也可以使用android帶的OMXCodec解碼器,OMXCodec解碼器是對OMX的一個封裝.其中ffmpeg解碼器主要輸出YUV420P的幀,而OMXCodec解碼器輸出的格式就多樣化,因具體的平臺不同而不同.
使用OMXCodec解碼器解出來的視頻,可以讓它自己輸出,只要在打開解碼器的時候給它傳個ANativeWindow:
解碼函數(shù)read出來的是MediaBuffer,其實(shí)是GraphicBuffer,不需要關(guān)心它的格式,只需要queueBuffer它,然后設(shè)置好render完成,并release它:
值得說明的是,在創(chuàng)建OMXCodec的時候,也可以傳入kKeyColorFormat來指定成想要的格式,但是不幸的是,有時候并不會支持你想要的, 比如有的手機(jī)就不支持HAL_PIXEL_FORMAT_YV12,而是使用了一種內(nèi)部格式,糾結(jié)吧,所以還是讓它自己輸出比較好.
在采用ffmpeg解碼器時,目前我所知道的,輸出YUV420P有兩種方法,一種是通過Lock ANativeWindow寫入YUV數(shù)據(jù),一種是通過opengles在片斷著色器中將YUV數(shù)據(jù)通過公式轉(zhuǎn)換成RGB輸出.
參考AwesomePlayer.cpp,會發(fā)現(xiàn)有個SoftwareRenderer的東東,這個類可以輸出 HAL_PIXEL_FORMAT_YV12, YUV420P->YV12的轉(zhuǎn)換其實(shí)很簡單,就是UV分量的存儲位置不一樣,拷貝時變換下就可以了.這個是Lock ANativeWindow的方法.里面還有一個AwesomeNativeWindowRenderer,其實(shí)就是上面提到的讓OMXCodec自己去輸出視頻的方法.
我在實(shí)踐中發(fā)現(xiàn),有些手機(jī)的SoftwareRenderer沒有處理好,特別是刷第三方ROM的時候,會花屏,所以需要自己手動從SoftwareRenderer.cpp中提取代碼,其實(shí)就是操作ANativeWindow的一些函數(shù):
上面的代碼省略了很多,只是一個基本的流程.android的源碼中還有一個gl2_yuvtex.cpp,里面有輸出YUV的方法,是采用了初始化 egl和opengles,然后創(chuàng)建GraphicBuffer寫入數(shù)據(jù),跟據(jù)GraphicBuffer創(chuàng)建EGLImageKHR,最后調(diào)用 opengles的擴(kuò)展GL_OES_EGL_image_external 輸出YUV,這種方法我也把它歸屬于LockAnativeWindow方法,因?yàn)檫@個方法就是上面的底層實(shí)現(xiàn).
Lock AnativeWindow方法優(yōu)點(diǎn)是底層有平臺實(shí)現(xiàn),非???缺點(diǎn)是,在lockBuffer之后,我們可以拿到y(tǒng)分量的行字節(jié)數(shù),即stride,但是沒有辦法獲取到uv分量的stride,跟據(jù)一般情況下應(yīng)該是y_stride/2然后按16字節(jié)對齊,但是有些廠商不按常理出牌,這個值不一定是這樣的,導(dǎo)致結(jié)果就是花屏或者內(nèi)存Abort,所以得適配手機(jī),麻煩!
再來說說使用opengles將YUV轉(zhuǎn)換成RGB輸出的方法,這種方法很早有就人使用了,最早的時候就使用軟件將YUV轉(zhuǎn)換成RGB輸出,但是效率太低了,于是大神們將眼光投向了opengles的可編程片段著色器,將YUV的轉(zhuǎn)換放到著色器去做,硬件處理是非??斓?這樣就大大提高了效率,具體的做法是:初始化EGL(參考gl2_yuvtex.cpp)->創(chuàng)建著色器程序并編譯連接->創(chuàng)建并上傳紋理->畫三角形.下面是頂點(diǎn)和紋理坐標(biāo),著色器代碼:
要注意的是,EGLContex和線程相關(guān),是opengles的狀態(tài)機(jī).使用這種方法要注意,在有些老的機(jī)器上,使用glTexImage2D或 glTexSubImage2D更新紋理時非常慢,一幀720x576的圖片可達(dá)80ms,這樣的話,就不要用這種方法渲染了,除非你可以舍棄清晰度,在新的硬件上,一般都能在幾個ms內(nèi).
使用opengles來渲染,還有其他的方法,就是使用OES擴(kuò)展,在安卓源碼里有例子gl2_yuv.cpp,可以參考使用,使用 glEGLImageTargetTexture2DOES上傳紋理沒有問題,一般都非???但是兼容性不好,原因和使用nativewindow直接渲染是相同的.
經(jīng)典必看android視頻下載教程,從入門到精通的android視頻下載!
【免責(zé)聲明】本文部分系轉(zhuǎn)載,轉(zhuǎn)載目的在于傳遞更多信息,并不代表本網(wǎng)贊同其觀點(diǎn)和對其真實(shí)性負(fù)責(zé)。如涉及作品內(nèi)容、版權(quán)和其它問題,請?jiān)?0日內(nèi)與聯(lián)系我們,我們會予以更改或刪除相關(guān)文章,以保證您的權(quán)益!