本文主要記錄閱讀源碼的部分心得
源碼地址 : https://github.com/google/grafika
我的:https://github.com/CL-window/openGL_learn.git
這個代碼雖然有一段時間了,但是其中的關於相機部分 還是很值得看一下的
1. mp4播放:PlayMovieActivity TextureView
PlayMovieSurfaceActivity in SurfaceView
MediaExtractor 分解音視頻
MediaCodec 播放,需要設置輸出的 Surface
decoder.configure(format, mOutputSurface, null, 0);
// 對輸入的數據流進行編碼或者解碼處理
decoder.dequeueInputBuffer // 獲得這個用來作爲媒體文件源碼的ByteBuffer(從輸入的buffers的數組中)的索引位置
decoder.queueInputBuffer // 使用帶有媒體文件源碼的ByteBuffer之後,通過調用此方法來釋放緩存區的所有權
decoder.dequeueOutputBuffer // 獲得你接收到結果的ByteBuffer的索引位置
decoder.releaseOutputBuffer // 釋放所有權
1.1 需要在 UI線程執行的代碼 可以 通過 Handler.sendMessage 實現
// Send message through Handler so it runs on the right thread.
mLocalHandler.sendMessage(mLocalHandler.obtainMessage(MSG_PLAY_STOPPED, mFeedback));
private static class LocalHandler extends Handler {
@Override
public void handleMessage(Message msg) {
int what = msg.what;
switch (what) {
case MSG_PLAY_STOPPED:
PlayerFeedback fb = (PlayerFeedback) msg.obj;
fb.playbackStopped();
break;
default:
throw new RuntimeException("Unknown msg " + what);
}
}
}
2. ContinuousCaptureActivity
錄製出來的 方向不對, 解決 :mEncoderSurface.makeCurrentReadFrom(mDisplaySurface);
即使用預覽的畫面錄製
預覽的方向 camera.setDisplayOrientation (適配2.2之上的手機)
parameters.set("orientation", "portrait")或者parameters.setRotation(90) (適配下2.2以下)
surfaceCreated 裏
預覽顯示使用的和 錄製視頻 使用的是相同的 EGLContext ,封裝在 EglCore 裏,同時還封裝了(EGLDisplay,EGLConfig)
WindowSurface 封裝 EGLSurface
設置相機預覽,使用 mCameraTexture.setOnFrameAvailableListener 監聽回調
Camera.setPreviewTexture
Camera.startPreview()
在有一幀數據到達時,先調用
EGL14.eglMakeCurrent(mEGLDisplay, mEGLSurface, mEGLSurface, mEGLContext)
通知GPU以及OPENGL ES在執行繪圖指令的時候,是在當前mEGLContext這個上下文繪製在mEGLSurface上的
這樣繪製就繪製在我們的佈局SurfaceView 上
updateTexImage() // 更新紋理圖像爲從圖像流中提取的最近一幀
getTransformMatrix(float[] mtx) // 提取最近調用的updateTexImage()爲紋理圖像設置的4×4的紋理座標變換矩陣
預覽 mDisplaySurface 和 錄製mEncoderSurface 使用 不同 Surface, 但是共用EGLContext,還有一個mCameraTexture 真正獲取相機的返回數據
錄製的 MediaCodec createInputSurface ,和 錄製mEncoderSurface 共用一個 Surface,這樣就保證錄製進去的是相機返回的數據
#camera 默認是橫屏 ,所以 width 爲豎屏時的高,height爲豎屏時的寬
3. TextureFromCameraActivity
支持 縮放 大小 旋轉 改變
主要是 Sprite2d 這個類 Matrix 提供的方法,通過 translateM ,rotateM,scaleM變化一個 4*4 的矩陣
這個類使用的是Matrix
float[] modelView = mModelViewMatrix;
Matrix.setIdentityM(modelView, 0);
Matrix.translateM(modelView, 0, mPosX, mPosY, 0.0f);
if (mAngle != 0.0f) {
Matrix.rotateM(modelView, 0, mAngle, 0.0f, 0.0f, 1.0f);
}
Matrix.scaleM(modelView, 0, mScaleX, mScaleY, 1.0f);
後面就是通知 GL 繪製 grafika.gles.Sprite2d.draw(gles.FlatShadedProgram, float[])
4. CameraCaptureActivity
GLSurfaceView.queueEvent() 運行在GL線程
根據不同選擇使用不同shader處理顯示畫面
CameraSurfaceRenderer.updateFilter 裏處理
mFullScreen.changeProgram(new Texture2dProgram(programType));
Texture2dProgram.java裏定義了shader,使用 不同 Program ,GLES20.glDeleteProgram