一、app层对fwk层的调用
frameworks/base/core/java/android/hardware/camera2/impl/CameraCaptureSessionImpl.java
app层在configure完成时,会调用到 finalizeOutputConfigurations,用于表示configure结束。
public void finalizeOutputConfigurations(
List<OutputConfiguration> outputConfigs) throws CameraAccessException {
synchronized (mDeviceImpl.mInterfaceLock) {
checkNotClosed();
mDeviceImpl.finalizeOutputConfigs(outputConfigs);
}
}
其中app层是用传递下来一个OutputConfiguration参数下来,里面是会包含很多信息,如对应是哪个mSurfaces,以及是否旋转mRotation等等。如下是OutputConfiguration类里的私有成员
private ArrayList<Surface> mSurfaces;
private final int mRotation;
private final int mSurfaceGroupId;
// Surface source type, this is only used by the deferred surface configuration objects.
private final int mSurfaceType;
// The size, format, and dataspace of the surface when OutputConfiguration is created.
private final Size mConfiguredSize;
private final int mConfiguredFormat;
private final int mConfiguredDataspace;
// Surface generation ID to distinguish changes to Surface native internals
private final int mConfiguredGenerationId;
// Flag indicating if this config has deferred surface.
private final boolean mIsDeferredConfig;
// Flag indicating if this config has shared surfaces
private boolean mIsShared;
// The physical camera id that this output configuration is for.
private String mPhysicalCameraId;
最后是会调用到CameraDeviceImpl类里的接口方法
frameworks/base/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java
public void finalizeOutputConfigs(List<OutputConfiguration> outputConfigs){
...
for (OutputConfiguration config : outputConfigs) {
int streamId = -1;
for (int i = 0; i < mConfiguredOutputs.size(); i++) {
// Have to use equal here, as createCaptureSessionByOutputConfigurations() and
// createReprocessableCaptureSessionByConfigurations() do a copy of the configs.
if (config.equals(mConfiguredOutputs.valueAt(i))) {
streamId = mConfiguredOutputs.keyAt(i);
break;
}
}
...
mRemoteDevice.finalizeOutputConfigurations(streamId, config);
mConfiguredOutputs.put(streamId, config);
}
...}
在这里其实没有做太多的事情,主要是从outputConfigs里的个数数量来创建对应的streamid,再把streamid和outputConfig作为参数传递给fwk的native层,同时也放入到mConfiguredOutputs这个稀疏数组里,在切换模式时configurestream会检查这里的stream是否需要删除掉,如果切换后的模式里相应的stream与切换前一致,是不会从mConfiguredOutputs删除对应的stream,会直接给切换后的模式使用。
二、fwk的native层
binder::Status CameraDeviceClient::finalizeOutputConfigurations(int32_t streamId,
const hardware::camera2::params::OutputConfiguration &outputConfiguration) {
...
//从outputConfiguration里获取IGraphicBufferProducer,在创建本地的surface里会用到
const std::vector<sp<IGraphicBufferProducer> >& bufferProducers =
outputConfiguration.getGraphicBufferProducers();
...
std::vector<sp<Surface>> consumerSurfaces;
const std::vector<int32_t> &sensorPixelModesUsed =
outputConfiguration.getSensorPixelModesUsed();
for (auto& bufferProducer : bufferProducers) {
// Don't create multiple streams for the same target surface
ssize_t index = mStreamMap.indexOfKey(IInterface::asBinder(bufferProducer));
if (index != NAME_NOT_FOUND) {
ALOGV("Camera %s: Surface already has a stream created "
" for it (ID %zd)", mCameraIdStr.string(), index);
continue;
}
sp<Surface> surface;
//使用上面所获取到的bufferProducer,根据createSurfaceFromGbp来创建surface实例对象
res = SessionConfigurationUtils::createSurfaceFromGbp(mStreamInfoMap[streamId],
true /*isStreamInfoValid*/, surface, bufferProducer, mCameraIdStr,
if (!res.isOk())
return res;
consumerSurfaces.push_back(surface);//把创建好的surface实例对象压入consumerSurfaces队列里
}
//从这可以看到有多少个bufferproducer就会创建多少个surface,在普通相机拍照场景下,一般都是会有两个,预览和拍照
...
std::vector<int> consumerSurfaceIds;
err = mDevice->setConsumerSurfaces(streamId, consumerSurfaces, &consumerSurfaceIds);
if (err == OK) {
for (size_t i = 0; i < consumerSurfaces.size(); i++) {
sp<IBinder> binder = IInterface::asBinder(
consumerSurfaces[i]->getIGraphicBufferProducer());
ALOGV("%s: mStreamMap add binder %p streamId %d, surfaceId %d", __FUNCTION__,
binder.get(), streamId, consumerSurfaceIds[i]);
mStreamMap.add(binder, StreamSurfaceId(streamId, consumerSurfaceIds[i]));
}
if (deferredStreamIndex != NAME_NOT_FOUND) {
mDeferredStreams.removeItemsAt(deferredStreamIndex);
}
mStreamInfoMap[streamId].finalized = true;
mConfiguredOutputs.replaceValueFor(streamId, outputConfiguration);
}
在创建完相应的surface之后,还有一件事没有完成,就是所创建的surface与具体的stream是如何建立越来的呢?这个其实是通过setConsumerSurfaces来完成的,在这个方法里会传入streamid,及刚刚所有创建好的surfaces(consumerSurfaces),在这里面是会得到surfaceid,是与streamid相匹配的。同时注意到几个主要的map变量,mStreamMap,mStreamInfoMap和mConfiguredOutputs;mStreamMap是把bufferproducer,streamid,surfaceid建立一个映射表,mStreamInfoMap是streamid与streaminfo之间建立映射表,mConfiguredOutputs是把streamId和app层下发的outputConfiguration建立映射表。
在执行完上面的之后,是把对应的streamid和surfaceid及bufferproducer压入到mStreamMap表里,同时对该stream标记是已经configure完成,