一、createCaptureSession 参数讲解
frameworks\base\core\java\android\hardware\camera2\impl\CameraDeviceImpl.java
@Override
public void createCaptureSession(List<Surface> outputs,
CameraCaptureSession.StateCallback callback, Handler handler)
throws CameraAccessException {
List<OutputConfiguration> outConfigurations = new ArrayList<>(outputs.size());
//创建OutputConfiguration列表,并将每种Surface数据结构转换为OutConfiguration对象添加到列表里
//例如:pre callback pic 三中surface
for (Surface surface : outputs) {
outConfigurations.add(new OutputConfiguration(surface));
}
createCaptureSessionInternal(null, outConfigurations, callback,
checkAndWrapHandler(handler), /*operatingMode*/ICameraDeviceUser.NORMAL_MODE,
/*sessionParams*/ null);
}
1.1、第一个参数是一个范型为Surface的List,Surface就是用来创建流的,surface配置一般如下
1.预览,拍照,callback 三路流(我司相机photo默认配置)
2.预览,拍照,录像(我司相机录像默认配置)
3.预览,callback
4.预览,录像
预览Surface:就是相机预览区域,buffer轮转时,预览区的buffer就是要从这个预览Surface当中获取的,这个Surface一定要正确,否则就会导致session创建失败,预览区就会黑屏了;
拍照Surface:一般使用ImageReader对象来获取,ImageReader是系统提供的一个类,它的创建过程已经为我们创建好了一个Surface,我们直接使用它来当作拍照Surface,当拍照成功后,我们就可以从ImageReader.OnImageAvailableListener内部类的onImageAvailable回调方法中获取到一个ImageReader对象,再调用getPlanes()获取到Plane数组,一般取第一个Plane,继续调用getBuffer()就可以获取到拍摄的照片的byte数组了,
1.2、第二个参数callback的类型: StateCallback
frameworks\base\core\java\android\hardware\camera2\CameraCaptureSession.java
session创建成功后,通过回调接口的public abstract void onConfigured(@NonNull CameraCaptureSession session)方法返回一个CameraCaptureSession对象给我们
而真正的实现是一个CameraCaptureSessionImpl对象,我们就可以使用CameraCaptureSessionImpl对象里的方法
E:\Q\framework\base\core\java\android\hardware\camera2\impl\CameraCaptureSessionImpl.java
1.3、第三个参数Handler:openCamera也一样,为了保证线程不发生切换,我们在应用进程的哪个工作线程中执行createCaptureSession,那么framework回调我们时,也会通过这个handler把回调消息发送到当前handler线程的Looper循环上
二、createCaptureSessionInternal
1.配置surface
configureSuccess = configureStreamsChecked(inputConfig, outputConfigurations, operatingMode,sessionParams); 2.创建成功实例化一个session实例,然后操作当前会话session里面的函数
newSession = new CameraCaptureSessionImpl(mNextSessionId++, input,callback, executor, this, mDeviceExecutor, configureSuccess);
private void createCaptureSessionInternal(InputConfiguration inputConfig,
List<OutputConfiguration> outputConfigurations,
CameraCaptureSession.StateCallback callback, Executor executor,
int operatingMode, CaptureRequest sessionParams)
{
if (DEBUG) {
Log.d(TAG, "createCaptureSessionInternal");
}
checkIfCameraClosedOrInError();
boolean isConstrainedHighSpeed =
(operatingMode == ICameraDeviceUser.CONSTRAINED_HIGH_SPEED_MODE);
if (isConstrainedHighSpeed && inputConfig != null) {
throw new IllegalArgumentException("Constrained high speed session doesn't support"
+ " input configuration yet.");
}
// Notify current session that it's going away, before starting camera operations
// After this call completes, the session is not allowed to call into CameraDeviceImpl
if (mCurrentSession != null) {
mCurrentSession.replaceSessionClose();
}
// TODO: dont block for this
boolean configureSuccess = true;
CameraAccessException pendingException = null;
Surface input = null;
try {
// configure streams and then block until IDLE
configureSuccess = configureStreamsChecked(inputConfig, outputConfigurations,
operatingMode, sessionParams);
//重点此部分是用来配置流的
if (configureSuccess == true && inputConfig != null) {
input = mRemoteDevice.getInputSurface();
}
} catch (CameraAccessException e) {
configureSuccess = false;
pendingException = e;
input = null;
if (DEBUG) {