Android的Camera现在有新的api,但是要5.0之后才能用,书上的源码也是用老版本api,简单分析一下预览流程。为了篇幅部分中间的调用流程将会省略,只贴出核心代码。
EGL环境初始化
首先我们肯定是要初始化egl,Native层使用hanlder的形式来循环处理消息。
void MVRecordingPreviewController::prepareEGLContext(ANativeWindow* window, JavaVM *g_jvm, jobject obj, int screenWidth, int screenHeight, int cameraFacingId){
LOGI("Creating MVRecordingPreviewController thread");
this->g_jvm = g_jvm;
this->obj = obj;
this->_window = window;
this->screenWidth = screenWidth;
this->screenHeight = screenHeight;
this->facingId = cameraFacingId;
handler->postMessage(new Message(MSG_EGL_THREAD_CREATE));
//开启线程循环处理消息,没有消息会阻塞wait()
pthread_create(&_threadId, 0, threadStartCallback, this);
}
class MVRecordingPreviewHandler: public Handler {
private:
MVRecordingPreviewController* previewController;
public:
MVRecordingPreviewHandler(MVRecordingPreviewController* previewController, MessageQueue* queue) :
Handler(queue) {
this->previewController = previewController;
}
void handleMessage(Message* msg) {
int what = msg->getWhat();
switch (what) {
case MSG_EGL_THREAD_CREATE:
previewController->initialize();
break;
case MSG_EGL_CREATE_PREVIEW_SURFACE:
previewController->createPreviewSurface();
break;
case MSG_SWITCH_CAMERA_FACING:
previewController->switchCamera();
break;
case MSG_EGL_DESTROY_PREVIEW_SURFACE:
previewController->destroyPreviewSurface();
break;
case MSG_EGL_THREAD_EXIT:
previewController->destroy();
break;
case MSG_RENDER_FRAME:
previewController->renderFrame();
break;
}
}
};
真正的初始化逻辑
bool MVRecordingPreviewController::initialize() {
const EGLint attribs[] = { EGL_BUFFER_SIZE, 32, EGL_ALPHA_SIZE, 8, EGL_BLUE_SIZE, 8, EGL_GREEN_SIZE, 8, EGL_RED_SIZE, 8, EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
EGL_SURFACE_TYPE, EGL_WINDOW_BIT, EGL_NONE };
LOGI("Initializing context");
eglCore = new EGLCore();
eglCore->init();
this->createPreviewSurface();
//到此初始化egl环境已经完成
...
return true;
}
配置Camera的参数
配置这个参数会从Native层调用Java的Camera的API来获取配置。
@TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)
private CameraConfigInfo setUpCamera(final int id) throws CameraParamSettingException {
forcePreviewSize_640_480();
// forcePreviewSize_1280_720();
// printStackTrace(CameraLoader.class);
try {
// 1、开启Camera
t