上节说了Open camera成功之后,会返回CameraDeviceImpl,接下来就是创建会话。会话主要创建CameraCaptureSessionImpl
frameworks\base\core\java\android\hardware\camera2\impl\CameraDeviceImpl.java
public void createCaptureSession(List<Surface> outputs,
CameraCaptureSession.StateCallback callback, Handler handler)
throws CameraAccessException {
List<OutputConfiguration> outConfigurations = new ArrayList<>(outputs.size());
for (Surface surface : outputs) {
outConfigurations.add(new OutputConfiguration(surface));
}
createCaptureSessionInternal(null, outConfigurations, callback,
checkAndWrapHandler(handler), /*operatingMode*/ICameraDeviceUser.NORMAL_MODE,
/*sessionParams*/ null);
}
先是将Surface转换为OutputConfiguration
先看下Surface调用的地方
packages\apps\Camera2\src\com\android\camera\one\v2\OneCameraImpl.java
outputSurfaces.add(previewSurface);
outputSurfaces.add(mCaptureImageReader.getSurface());
mDevice.createCaptureSession(outputSurfaces, new CameraCaptureSession.StateCallback() {
这个就是多个outputSurfaces集合
看下定义的地方
public final class OutputConfiguration implements Parcelable {
是一个进程间共享的数据包,管理输出配置(包含增减sufrace 方向 宽高,可以看writeToParcel传递的数据)
private void createCaptureSessionInternal(InputConfiguration inputConfig,
List<OutputConfiguration> outputConfigurations,
CameraCaptureSession.StateCallback callback, Executor executor,
int operatingMode, CaptureRequest sessionParams) throws CameraAccessException {
……
// 如果调用createConstrainedHighSpeedCaptureSession 这个参数就为ture,在open的时候查看//metadata如果支持高帧率,就可以调用它去实现高帧率预览
boolean isConstrainedHighSpeed =
(operatingMode == ICameraDeviceUser.CONSTRAINED_HIGH_SPEED_MODE);
……//1.1 对outputConfigurations检查,是否有配置这些,有删除,没有添加
configureSuccess = configureStreamsChecked(inputConfig, outputConfigurations,
operatingMode, sessionParams);
if (configureSuccess == true && inputConfig != null) {
input = mRemoteDevice.getInputSurface();
}
……//1.2
newSession = new CameraCaptureSessionImpl(mNextSessionId++, input,
callback, executor, this, mDeviceExecutor, configureSuccess);
……//1.3
mCurrentSession = newSession;
1.1
public boolean configureStreamsChecked(InputConfiguration inputConfig,
List outputs, int operatingMode, CaptureRequest sessionParams)
throws CameraAccessException {
…
mRemoteDevice.beginConfigure();//执行到CameraDeviceClient::beginConfigure(函数等待实现)
…//1.1.1
// Add all new streams
for (OutputConfiguration outConfig : outputs) {
if (addSet.contains(outConfig)) {
//创建并配置输出流,会执行到CameraDeviceClient::createStream
int streamId = mRemoteDevice.createStream(outConfig);
mConfiguredOutputs.put(streamId, outConfig);
}
}
……//1.1.2
mRemoteDevice.endConfigure(operatingMode, null);
1.1.1
binder::Status CameraDeviceClient::createStream(
const hardware::camera2::params::OutputConfiguration &outputConfiguration,
/*out*/
int32_t* newStreamId) {
……
//该函数如下将OutputConfiguration中的配置信息转换保存到streamInfo (device3下面的对象),里面调用如下:
//surface = new Surface(gbp, useAsync);
// ANativeWindow *anw = surface.get(); 这个就能想起hal1的window
res = createSurfaceFromGbp(streamInfo, isStreamInfoValid, surface, bufferProducer);
……
//添加到 本地surfaces
surfaces.push_back(surface);
……//1.1.1.1
err = mDevice->createStream(surfaces, deferredConsumer, streamInfo.width,
streamInfo.height, streamInfo.format, streamInfo.dataSpace,
static_cast<camera3_stream_rotation_t>(outputConfiguration.getRotation()),
&streamId, physicalCameraId, &surfaceIds, outputConfiguration.getSurfaceSetID(),
isShared);
……
mStreamMap.add(binder, StreamSurfaceId(streamId, surfaceIds[i]));
……//保存信息,注意上层调用是OutputConfiguration,和这里的名字不一样,这里保存本地
mConfiguredOutputs.add(streamId, outputConfiguration);
mStreamInfoMap[streamId] = streamInfo;
status_t Camera3Device::createStream(const std::vector<sp<Surface>>& consumers,
bool hasDeferredConsumer, uint32_t width, uint32_t height, int format,
android_dataspace dataSpace, camera3_stream_rotation_t rotation, int *id,
const String8& physicalCameraId,
std::vector<int> *surfaceIds, int streamSetId, bool isShared, uint64_t consumerUsage) {
......
} else {
// 创建 Camera3OutputStream 实例,consumers是 Surface,
//Camera3OutputStream 的 mConsumer 成员 ,往下调用是Camera3IOStreamBase,再下一级是、、//Camera3Stream,所以最终创建的是Camera3Stream结构,Camera3OutputStream为外包装
newStream = new Camera3OutputStream(mNextStreamId, consumers[0],
width, height, format, dataSpace, rotation,
mTimestampOffset, physicalCameraId, streamSetId);
}
……
//保存对象
res = mOutputStreams.add(mNextStreamId, newStream);
1.1.2
binder::Status CameraDeviceClient::endConfigure(int operatingMode,
const hardware::camera2::impl::CameraMetadataNative& sessionParams) {
…
status_t err = mDevice->configureStreams(sessionParams, operatingMode);
…
}
Camera3Device::configureStreams
–>Camera3Device::filterParamsAndConfigureLocked
–>Camera3Device::configureStreamsLocked
–> mInterface->configureStreams(sessionBuffer, &config, bufferSizes)
–>Camera3Device::HalInterface::configureStreams
–>mHidlSession->configureStreams
mHidlSession在Camera3Device.h定义为
sphardware::camera::device::V3_2::ICameraDeviceSession mHidlSession
hardware\interfaces\camera\device\3.2\CameraDeviceSession.cpp
CameraDeviceSession::configureStreams
–>mDevice->ops->configure_streams 这个mDevice之前有赋值
执行hal的camera3_device_ops_t的configure_streams函数
hardware\rockchip\camera\AAL\Camera3HAL.cpp
hal_dev_configure_streams //hal会专门说这个函数
1.2
CameraCaptureSessionImpl(int id, Surface input,
CameraCaptureSession.StateCallback callback, Executor stateExecutor,
android.hardware.camera2.impl.CameraDeviceImpl deviceImpl,
Executor deviceStateExecutor, boolean configureSuccess) {
……//前面初始化参数,后面调用传入回调的onConfigured,跟open的时候相似,获取CameraCaptureSessionImpl
//内部还包含CameraDeviceImpl(ICameraDeviceUserWrapper)(CameraDeviceClient),然后包含//Camera3InputStream 包含Camera3Stream
if (configureSuccess) {
mStateCallback.onConfigured(this);
if (DEBUG) Log.v(TAG, mIdString + “Created session successfully”);
mConfigureSuccess = true;
}
}
CameraCaptureSession.StateCallback类的public abstract void onConfigured(@NonNull CameraCaptureSession session)回调到应用层,通知我们session创建成功了,那么我们就可以使用回调方法中的CameraCaptureSession参数,调用它的setRepeatingRequest方法来下预览了
小结:apk传下surface,调用createCaptureSession,将surface转换成本地的OutputConfiguration,检查下之前是否配置过,如果包含新的配置,调用mRemoteDevice .createStream也就是CameraDeviceClient ::createStream进入到cameraservice。该函数调用createSurfaceFromGbp转换成本地的surface和streamInfo。调用Camera3Device::createStream,这里面new一个Camera3OutputStream。后面调用mDevice->configureStreams配置之前准备好的stream。
最后创建一个会话类CameraCaptureSessionImpl。