Android P之Camera HAL3流程分析(3)

我们使用TextureView显示相机预览数据,Camera2的预览和拍照数据都是使用CameraCaptureSession会话来请求的
    private void startPreview() {
        SurfaceTexture mSurfaceTexture = mTextureView.getSurfaceTexture();
        mSurfaceTexture.setDefaultBufferSize(mPreviewSize.getWidth(), mPreviewSize.getHeight());
        //通过view创建surface对象
        Surface previewSurface = new Surface(mSurfaceTexture);
        try {
            mCaptureRequestBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
            //绑定请求和surface
            mCaptureRequestBuilder.addTarget(previewSurface);
            //预览数据会同时输出到previewSurface和mImageReader
            mCameraDevice.createCaptureSession(Arrays.asList(previewSurface, mImageReader.getSurface()), new
                                                                            CameraCaptureSession.StateCallback() {
                @Override
                public void onConfigured(CameraCaptureSession session) {
                    try {
                        //创建请求
                        mCaptureRequest = mCaptureRequestBuilder.build();
                        //保存相机会话对象
                        mCameraCaptureSession = session;
                        //开始预览
                        mCameraCaptureSession.setRepeatingRequest(mCaptureRequest, null, mCameraHandler);
                    }
                }
                @Override
                public void onConfigureFailed(CameraCaptureSession session) {

                }
            }, mCameraHandler);
        }
    }

createCaptureRequest阶段

alps/frameworks/base/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java
    public CaptureRequest.Builder createCaptureRequest(int templateType) {
        synchronized(mInterfaceLock) {
            CameraMetadataNative templatedRequest = null;
            templatedRequest = mRemoteDevice.createDefaultRequest(templateType);//创建default metadata

            // If app target SDK is older than O, or it's not a still capture template, enableZsl
            // must be false in the default request.
            if (mAppTargetSdkVersion < Build.VERSION_CODES.O ||
                    templateType != TEMPLATE_STILL_CAPTURE) {
                overrideEnableZsl(templatedRequest, false);
            }
            CaptureRequest.Builder builder = new CaptureRequest.Builder(
                    templatedRequest, /*reprocess*/false, CameraCaptureSession.SESSION_ID_NONE,
                    getId(), /*physicalCameraIdSet*/ null);

            return builder;
        }
    }

创建CameraMetadataNative对象,内在是创建CameraMetadata对象(CameraMetadata.cpp),对CameraMetadataNative对象的操作本质上都是操作CameraMetadata对象,即camera_metadata_t * mBuffer。至此我们就创建了CameraMetadata对象,其管理着一块buffer,buffer中保存的是某个场景预览、录像或拍照的默认metadata。

-----------------------------------------------------------------------------------------------------------------------------------
Builder的实现
   public Builder(CameraMetadataNative template, boolean reprocess,
        int reprocessableSessionId, String logicalCameraId,
            Set physicalCameraIdSet) {
            mRequest = new CaptureRequest(template, reprocess, reprocessableSessionId,
                logicalCameraId, physicalCameraIdSet);
    }
    private CaptureRequest(CameraMetadataNative settings, boolean isReprocess,
            int reprocessableSessionId, String logicalCameraId, Set physicalCameraIdSet) {
        mLogicalCameraId = logicalCameraId;
        mLogicalCameraSettings = CameraMetadataNative.move(settings);//保存camera_metadata_t
        mPhysicalCameraSettings.put(mLogicalCameraId, mLogicalCameraSettings);

        setNativeInstance(mLogicalCameraSettings);//保存mLogicalCameraSettings
        mIsReprocess = isReprocess;
        if (isReprocess) {
            if (reprocessableSessionId == CameraCaptureSession.SESSION_ID_NONE) {
                throw new IllegalArgumentException("Create a reprocess capture request with an " +
                        "invalid session ID: " + reprocessableSessionId);
            }
            mReprocessableSessionId = reprocessableSessionId;
        } else {
            mReprocessableSessionId = CameraCaptureSession.SESSION_ID_NONE;
        }
    }
-----------------------------------------------------------------------------------------------------------------------------------
alps/frameworks/av/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
typedef CameraMetadata CameraMetadataNative;
binder::Status CameraDeviceClient::createDefaultRequest(int templateId,
        /*out*/
        hardware::camera2::impl::CameraMetadataNative* request)
{
    CameraMetadata metadata;
    status_t err;
    if ( (err = mDevice->createDefaultRequest(templateId, &metadata) ) == OK &&
        request != NULL) {
        request->swap(metadata);//保存CameraMetadata对象的camera_metadata_t变量
    }
    return res;
}

-----------------------------------------------------------------------------------------------------------------------------------
swap的实现
void CameraMetadata::swap(CameraMetadata& other) {
    camera_metadata* thisBuf = mBuffer;
    camera_metadata* otherBuf = other.mBuffer;

    other.mBuffer = thisBuf;
    mBuffer = otherBuf;
}
-----------------------------------------------------------------------------------------------------------------------------------
alps/frameworks/av/services/camera/libcameraservice/device3/Camera3Device.cpp
status_t Camera3Device::createDefaultRequest(int templateId,
        CameraMetadata *request) {
    {
        Mutex::Autolock l(mLock);
        switch (mStatus) {
            case STATUS_ERROR:
                CLOGE("Device has encountered a serious error");
                return INVALID_OPERATION;
            case STATUS_UNINITIALIZED:
                CLOGE("Device is not initialized!");
                return INVALID_OPERATION;
            case STATUS_UNCONFIGURED:
            case STATUS_CONFIGURED:
            case STATUS_ACTIVE:
                // OK
                break;
        }

        if (!mRequestTemplateCache[templateId].isEmpty()) {
            *request = mRequestTemplateCache[templateId];
            mLastTemplateId = templateId;
            return OK;
        }
    }

    camera_metadata_t *rawRequest;
    status_t res = mInterface->constructDefaultRequestSettings(
            (camera3_request_template_t) templateId, &rawRequest);

    {
        set_camera_metadata_vendor_id(rawRequest, mVendorTagId);
        mRequestTemplateCache[templateId].acquire(rawRequest);//保存camera_metadata_t

        *request = mRequestTemplateCache[templateId];
        mLastTemplateId = templateId;
    }
    return OK;
}
-----------------------------------------------------------------------------------------------------------------------------------
acquire的实现
CameraMetadata             mRequestTemplateCache[CAMERA3_TEMPLATE_COUNT];
CameraMetadata::CameraMetadata(size_t entryCapacity, size_t dataCapacity) :
        mLocked(false)
{
    mBuffer = allocate_camera_metadata(entryCapacity, dataCapacity);
}
void CameraMetadata::acquire(camera_metadata_t *buffer) {
    clear();
    mBuffer = buffer;
}
-----------------------------------------------------------------------------------------------------------------------------------

status_t Camera3Device::HalInterface::constructDefaultRequestSettings(
        camera3_request_template_t templateId,
        /*out*/ camera_metadata_t **requestTemplate) {
    //定义回调函数,其中返回值为status和requestTemplate
    auto requestCallback = [&status, &requestTemplate]
            (common::V1_0::Status s, const device::V3_2::CameraMetadata& request) {
            status = s;
            if (status == common::V1_0::Status::OK) {
                const camera_metadata *r =
                        reinterpret_cast(request.data());//request=CameraMetadata
                size_t expectedSize = request.size();
                int ret = validate_camera_metadata_structure(r, &expectedSize);
                if (ret == OK || ret == CAMERA_METADATA_VALIDATION_SHIFTED) {
                    *requestTemplate = clone_camera_metadata(r);//拷贝返回值的内容
                }
            }
        };
    hardware::Return err;
    RequestTemplate id;
    switch (templateId) {
        case CAMERA3_TEMPLATE_PREVIEW:
            id = RequestTemplate::PREVIEW;
            break;
        case CAMERA3_TEMPLATE_STILL_CAPTURE:
            id = RequestTemplate::STILL_CAPTURE;
            break;
        case CAMERA3_TEMPLATE_VIDEO_RECORD:
            id = RequestTemplate::VIDEO_RECORD;
            break;
        case CAMERA3_TEMPLATE_VIDEO_SNAPSHOT:
            id = RequestTemplate::VIDEO_SNAPSHOT;
            break;
        case CAMERA3_TEMPLATE_ZERO_SHUTTER_LAG:
            id = RequestTemplate::ZERO_SHUTTER_LAG;
            break;
        case CAMERA3_TEMPLATE_MANUAL:
            id = RequestTemplate::MANUAL;
            break;
        default:
            // Unknown template ID, or this HAL is too old to support it
            return BAD_VALUE;
    }
    err = mHidlSession->constructDefaultRequestSettings(id, requestCallback);//通过回调函数返回requestTemplate
    return res;
}
alps/vendor/mediatek/proprietary/hardware/mtkcam3/main/hal/device/3.x/device/CameraDevice3SessionImpl.cpp
ThisNamespace::
constructDefaultRequestSettings(RequestTemplate type, constructDefaultRequestSettings_cb _hidl_cb){
    ITemplateRequest* obj = NSTemplateRequestManager::valueFor(getInstanceId());
    if  (obj == nullptr) {
        obj = ITemplateRequest::getInstance(getInstanceId());
        NSTemplateRequestManager::add(getInstanceId(), obj);
    }
    CameraMetadata metadata;
    {
        camera_metadata const* p_camera_metadata = obj->getData(static_cast(type));
        size_t size = mStaticInfo.mMetadataConverter->getCameraMetadataSize(p_camera_metadata);
        metadata.setToExternal((uint8_t *)p_camera_metadata, size, false/*shouldOwn*/);//转换格式
    }
    _hidl_cb(Status::OK, metadata);//返回metadata
    return Void();
}
alps/vendor/mediatek/proprietary/hardware/mtkcam/utils/metastore/templateRequest/TemplateRequest.cpp
ITemplateRequest*
ITemplateRequest::
getInstance(int iOpenId){
    TemplateRequest* p = new TemplateRequest();
    if(p != NULL) {
        p->onCreate(iOpenId);
    }
    return p;
}
TemplateRequest::
onCreate(int iOpenId){
    auto pHalDeviceList = MAKE_HalLogicalDeviceList();
    IHalSensorList* pHalSensorList = MAKE_HalSensorList();
    // get main sensor from logical device list.
    auto sensorIdList = pHalDeviceList->getSensorId(iOpenId);
    // check 4cell type
    MUINT32 sensorDev = (MUINT32)pHalSensorList->querySensorDevIdx(sensorIdList[0]);
    NSCam::SensorStaticInfo sensorStaticInfo;
    pHalSensorList->querySensorStaticInfo(sensorDev, &sensorStaticInfo);
    uint32_t u4RawFmtType = sensorStaticInfo.rawFmtType;
    bool is4CellSensor = (( u4RawFmtType == SENSOR_RAW_4CELL ||
                            u4RawFmtType == SENSOR_RAW_4CELL_BAYER ||
                            u4RawFmtType == SENSOR_RAW_4CELL_HW_BAYER) ? true : false);

    int32_t sensorType = pHalSensorList->queryType(sensorIdList[0]);
    const char* sensorDrvName = pHalDeviceList->queryDriverName(iOpenId);
    mInfo = Info(iOpenId, sensorType, sensorDrvName, is4CellSensor);

    //  Standard template types
    for (int type = CAMERA3_TEMPLATE_PREVIEW; type < CAMERA3_TEMPLATE_COUNT; type++)
    {
        camera_metadata* metadata = NULL;
        IMetadata mtkMetadata;
        status_t status = constructRequestMetadata(type, metadata, mtkMetadata);
        mMapRequestTemplate.add(type, metadata);
        mMapRequestTemplateMetadata.add(type, mtkMetadata);
    }
    return OK;
}
TemplateRequest::
constructRequestMetadata(
    int const           requestType,
    camera_metadata*&   rpMetadata,
    IMetadata&          rMtkMetadata
){
    //-----(1)-----//
    //get static informtation from customization (with camera_metadata format)
    //calculate its entry count and data count
    if  ( OK != (status = impConstructRequestMetadata(rMtkMetadata, requestType)) ) {
        MY_LOGE("Unable evaluate the size for camera static info - status[%s(%d)]\n", ::strerror(-status), -status);
        return  status;
    }

    //calculate its entry count and data count
    // init converter
    IMetadataTagSet tagInfo;
    setTagInfo(tagInfo);
    sp pConverter = IMetadataConverter::createInstance(tagInfo);

    size_t entryCount = 0;
    size_t dataCount = 0;
    MBOOL ret = pConverter->get_data_count(rMtkMetadata, entryCount, dataCount);

    //-----(2)-----//
    // overwrite
    updateData(rMtkMetadata);

    //-----(3)-----//
    // convert to android metadata
    pConverter->convert(rMtkMetadata, rpMetadata);
    ::sort_camera_metadata(rpMetadata);

    return  status;
}

你可能感兴趣的:(Camera)