以 影像播放器實作 - 使用 OpenGL, MediaCodec 與 SurfaceTexture 為基礎, 加入 android.hardware.camera2 實作攝影機預覽功能.

<<預覽建立流程>>

步驟 1: 建立 GLSurfaceView, 這是 camera2 所需的 EGL 環境

protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

// Step 1: Create GLSurfaceView for camera2 required EGL environment
GLSurfaceView glSurfaceView;
glSurfaceView = new GLSurfaceView(this);
glSurfaceView.setEGLContextClientVersion(2);
glRenderer = new SampleGLRenderer();
glSurfaceView.setRenderer(glRenderer);


步驟 2: 以 SurfaceTexture 建立 Surface

if (id == R.id.action_preview) {
// Step 2: Create Surface from SurfaceTexture
if (surfaceTexture == null) {
surfaceTexture = new SurfaceTexture(glRenderer.getTextureHandle());
surfaceTexture.setOnFrameAvailableListener(this);
surface = new Surface(surfaceTexture);
}


步驟 3: 取得 CameraManager 服務, 尋找第一個攝影機 ID 並開啟

CameraManager cameraManager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);

// Find camera ID. This sample uses first camera only
String cameraID = "";
try {
cameraID = cameraManager.getCameraIdList()[0];
} catch (CameraAccessException e) {
e.printStackTrace();
}

// Setup camera availability callbacks
cameraManager.registerAvailabilityCallback(cameraAvailabilityCallback, null);

// Open camera with CameraDevice state callback registered
try {
cameraManager.openCamera(cameraID, cameraDeviceStateCallback, null);
} catch (CameraAccessException e) {
e.printStackTrace();
}


步驟 4: 建立預覽的 capture request builder. 並將以 SurfaceTexture 建立 的 Surface 設定為預覽輸出目標 (target) 

public void onOpened(CameraDevice cameraDevice) {
try {
previewRequestBuilder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
} catch (CameraAccessException e) {
e.printStackTrace();
}
previewRequestBuilder.addTarget(surface);

步驟 5: 建立預覽的 capture session

 cameraDevice.createCaptureSession(Arrays.asList(surface), cameraCaptureSessionStateCallback, null);

 

步驟 6: 送出預覽要求 (Request) 

CaptureRequest previewRequest = previewRequestBuilder.build();
cameraCaptureSession.setRepeatingRequest(previewRequest,
cameraCaptureSessionCaptureCallback, null);


步驟 7: onFrameAvailable() 通知預覽影像更新

public void onFrameAvailable(SurfaceTexture surfaceTexture) {
// Step 7: onFrameAvailable() inform texture update of preview
glRenderer.updateTexture(surfaceTexture);
}


步驟 8: SurfaceTexture 更新纹理 (samplerExternalOES)影像

public void onDrawFrame(GL10 gl) {
// Step 8: SurfaceTexture update texture image in context of GLSurfaceView.Renderer.onDrawFrame()
if(surfaceTexture != null) {
// Here is right context of calling SurfaceTexture.updateTexImage()
surfaceTexture.updateTexImage();
surfaceTexture = null;
}


步驟 9: 輸出影像

sampleGL20Video.draw();

 

<<原始碼>>

GitHub SampleCamera2  

(完)

 

文章標籤
創作者介紹
創作者 版大 的頭像
版大

嵌入式系統

版大 發表在 痞客邦 留言(0) 人氣()