相机fwk层surface如何与bufferqueue建立起联系

一、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完成,

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值