上一篇文章android Camera API1+HAL1 open camera流程 & Android M已经跟踪了open camera在framework层的整个流程,这篇文章主要分析StartPreview的流程。
很多博主分析camera流程的相关流程都是从java接口层一鼓作气分析到hal层,这样分析的好处是流程连贯。但整个分析流程则非常长,贴上代码的话,文章也变得异常的长,让人望而生畏,失去阅读的欲望。
对hal层的分析对于很多读者来说是不关心的,我打算将framework层和hal层的流程分开分析,framework层各芯片厂商都是一致的,分析的文章也更具普适性。目前分析流程的文章只针对framework层的代码,必要时捎带讲述下hal层的和framework层的接口部分。后续的文章会单独分析下TI 和高通hal层内部流程和架构。
闲言少叙,还是从官方示例开始分析,以下是一段官方示例
/** A basic Camera preview class */
public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback {
private SurfaceHolder mHolder;
private Camera mCamera;
public CameraPreview(Context context, Camera camera) {
super(context);
mCamera = camera;
// Install a SurfaceHolder.Callback so we get notified when the
// underlying surface is created and destroyed.
mHolder = getHolder();
mHolder.addCallback(this);
// deprecated setting, but required on Android versions prior to 3.0
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
public void surfaceCreated(SurfaceHolder holder) {
// The Surface has been created, now tell the camera where to draw the preview.
try {
mCamera.setPreviewDisplay(holder);
mCamera.startPreview();
} catch (IOException e) {
Log.d(TAG, "Error setting camera preview: " + e.getMessage());
}
}
public void surfaceDestroyed(SurfaceHolder holder) {
// empty. Take care of releasing the Camera preview in your activity.
}
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
// If your preview can change or rotate, take care of those events here.
// Make sure to stop the preview before resizing or reformatting it.
if (mHolder.getSurface() == null){
// preview surface does not exist
return;
}
// stop preview before making changes
try {
mCamera.stopPreview();
} catch (Exception e){
// ignore: tried to stop a non-existent preview
}
// set preview size and make any resize, rotate or
// reformatting changes here
// start preview with new settings
try {
mCamera.setPreviewDisplay(mHolder);
mCamera.startPreview();
} catch (Exception e){
Log.d(TAG, "Error starting camera preview: " + e.getMessage());
}
}
}
打开camera后,我们需要预览画面,这就需要一个surface作为画布,将创建的surface传递到hal层,供hal往surface里填充数据,进而显示camera采集画面。
开始预览之前,需要先设置预览
0 setPreviewDisplay
- Camera.java
public final void setPreviewDisplay(SurfaceHolder holder) throws IOException {
if (holder != null) {
setPreviewSurface(holder.getSurface());
} else {
setPreviewSurface((Surface)null);
}
}
public native final void setPreviewSurface(Surface surface) throws IOException;
从SurfaceHolder中获取到一个surface,作为setPreviewSurface的参数传递下去,setPreviewSurface是一个native函数,直接调用到JNI层。
- android_hardware_Camera.cpp
{
"setPreviewSurface",
"(Landroid/view/Surface;)V",
(void *)android_hardware_Camera_setPreviewSurface },
static void android_hardware_Camera_setPreviewSurface(JNIEnv *env, jobject thiz, jobject jSurface)
{
ALOGV("setPreviewSurface");
sp<Camera> camera = get_native_camera(env, thiz,