Android相機API2,基于GLSurfaceView+SurfaceTexture實現相機預覽,集成的相機算法采用GPU方案,簡要流程如下(不疊加相機算法的預覽顯示流程也大體如此,只是去掉了算法部分):
進入相機:
1,新建實現了GLSurfaceView.Renderer接口的自定義類CameraRenderer,初始化GLSurfaceView,將兩者綁定在一起,GLSurfaceView作為View組件來顯示相機預覽;
相機啟動:
1,在起預覽配流時,創建SurfaceTexture,用它來接收相機預覽數據;
OpenGL初始化:
1,在Surface創建時會觸發回調CameraRenderer.onSurfaceCreated,在里面獲取當前的GLSurfaceView的EGLContext,并將其傳遞給相機算法,使得允許相機算法和GLSurfaceView共享GPU資源;
循環渲染:
1,當有預覽幀來時,觸發回調SurfaceTexture.OnFrameAvailable,在里面調用glSurfaceView.requestRender進行重繪;
2,glSurfaceView.requestRender中釋放鎖喚醒GLThread的線程執行,里面循環檢查是否需要進行繪制,需要的話就調CameraRenderer.onDrawFrame;
3,onDrawFrame中調surfaceTexture.updateTexImage,將最新的相機預覽幀數據更新到SurfaceTexture內部的紋理中;
4,調算法處理接口,輸入紋理ID,輸出也是紋理ID;
5,將這個紋理ID作為數據源,繪制到GLSurfaceView上,至此預覽完成這一幀顯示;后續重復“循環渲染”的步驟;
總結:
1,創建GLSurfaceView,這個作為View組件顯示相機預覽;
2,在相機起預覽配流時,創建SurfaceTexture,用來接收相機預覽數據;
3,OpenGL要初始化;
4,最后就是循環繪制的流程,當有預覽幀來時,觸發回調SurfaceTexture.OnFrameAvailable,在里面觸發重繪,更新最新預覽數據到SurfaceTexture內部紋理中,將紋理ID輸入算法進行處理,算法處理后輸出更新后的紋理ID,最后將這個紋理ID作為數據源繪制到GLSurfaceView上;
UML類圖如下。