歡迎訪問我的blog:
http://blog.thinkinside.me
關於android中openmax中hardware decoder的調用中,整合過程比較簡單。主要是對OMXCodec的封裝進行調用。
這里記錄一下碰到的主要的問題:
1 現象:開關幾次后程序出現crash。
幾台設備都有此現象,內存大的機器可以開關的次數多些,內存小的機器開關次數少。video尺寸小的可開關的次數多些,video尺寸小的可開關次數少。典型的內存泄露,而且與video decoder的解碼buffer有關。經過痛苦萬分的無數次打log,發現GraphicBuffer沒有釋放。
解決方案也簡單的可以,從surface中申請的ANativewindow沒有被釋放。也就是
ANativeWindow_fromSurface()........ANativeWindow_release()
沒有成對調用。
2 現象:播放某些流或者DTV時出現解碼錯誤且不再恢復
由於我們的framework和OMXCodec的調用方式,導致過早decoder退出。具體些講,由於我們的封裝接口調用OMXCodec的解碼是通過read函數調用實現的。read內部會去調用tracksource->read.如果出現數據不足或者錯誤太多,容易導致tracksource的buffer不夠。我們這時候會在tracksource的read給出數據不足的返回值。OMXcodec的封裝認為收到這個錯誤返回值把自己的狀態設置為Endofstream,之后就不再解碼了。
解決方案:參考AnotherPacketSource。在tracksource read阻塞住,等新的數據填入。
3 現象:解碼時卡死
這個是由於調用OMXCodec的調用為阻塞導致的。我們往codec塞數據和decode的調用都是在一個線程中。先塞數據,再decode。如果decode中出現錯誤數據過多或者數據不足時,按照上一個問題的解決方案,會出現等待新數據輸入的過程。可是這時候在framework中decode函數無法返回,也就沒有辦法輸入更多數據了。典型的死鎖過程。
解決方案:放棄上一個方案中的阻塞方法。出現數據不足時,給OMXCodec返回一個空的MediaBuffer,並且告知沒有錯誤發生。上面兩個問題完美解決。
4 現象:無法使用overlay
使用系統默認播放器時,會有Log表明在SurfaceFlinger做doComposeSurfaces函數時使用的是HWC_OVERLAY。而我們的framework只能使用到HWC_FRAMEBUFFER。對比awesome player對OMXCodec的調用,發現調用的OMXCodec的接口,以及nativewindow的操作並沒有太大區別。
最后只好從Java層開始review,終於在 MediaPlayerService::Client::setVideoSurfaceTexture中發現了native_window_api_connect(anw.get(), NATIVE_WINDOW_API_MEDIA);調用。
解決方案: 在申請好nativewindow后調用native_window_api_connect,在release nativewindow前調用native_window_api_disconnect。