qcom HAL3 face detect流程梳理

不熟悉java,所以梳理从JNI开始
frameworks/base/core/java/android/hardware/Camera.java

下发facedetect命令:
    public final void startFaceDetection() {
        if (mFaceDetectionRunning) {
            throw new RuntimeException("Face detection is already running");
        }
        _startFaceDetection(CAMERA_FACE_DETECTION_HW);
        mFaceDetectionRunning = true;
    }


通过JNI调用native
frameworks/base/core/jni/android_hardware_Camera.cpp

static void android_hardware_Camera_startFaceDetection(JNIEnv *env, jobject thiz,
        jint type)
{
    status_t rc = camera->sendCommand(CAMERA_CMD_START_FACE_DETECTION, type, 0);
}

sendcommand命令由frameworks/av/services/camera/libcameraservice/api1/Camera2Client.cpp文件接收
并执行commandStartFaceDetectionL函数

status_t Camera2Client::commandStartFaceDetectionL(int /*type*/) {

    switch (l.mParameters.state) {
        case Parameters::DISCONNECTED:
        case Parameters::STOPPED:
        case Parameters::WAITING_FOR_PREVIEW_WINDOW:
        case Parameters::STILL_CAPTURE:
            ALOGE("%s: Camera %d: Cannot start face detection without preview active",
                    __FUNCTION__, mCameraId);
            return INVALID_OPERATION;
        case Parameters::PREVIEW:
        case Parameters::RECORD:
        case Parameters::VIDEO_SNAPSHOT:
            // Good to go for starting face detect
            break;
    }

    res = updateRequests(l.mParameters);      //继续执行下发facedetect命令
}


status_t Camera2Client::updateRequests(Parameters &params) { //这里就是下发更新参数的通道,不仅仅是facedetect,所有的请求都经此
    res = mStreamingProcessor->incrementStreamingIds();

    res = mStreamingProcessor->updatePreviewRequest(params);

    res = mStreamingProcessor->updateRecordingRequest(params);

    if (params.state == Parameters::PREVIEW) {
        res = startPreviewL(params, true); //判断当前模式,确定是preview还是recording
    } else if (params.state == Parameters::RECORD ||
            params.state == Parameters::VIDEO_SNAPSHOT) {
        res = startRecordingL(params, true);
    }
}


status_t Camera2Client::startPreviewL(Parameters &params, bool restart) {

    int lastPreviewStreamId = mStreamingProcessor->getPreviewStreamId();
    res = mStreamingProcessor->updatePreviewStream(params);

    bool previewStreamChanged = mStreamingProcessor->getPreviewStreamId() != lastPreviewStreamId;

    int lastJpegStreamId = mJpegProcessor->getStreamId();

    res = updateProcessorStream(mJpegProcessor, params);
    
    bool jpegStreamChanged = mJpegProcessor->getStreamId() != lastJpegStreamId;

    if (callbacksEnabled) {
        res = mCallbackProcessor->updateStream(params);
        outputStreams.push(getCallbackStreamId());
    } 

    if (params.useZeroShutterLag() &&
            getRecordingStreamId() == NO_STREAM) {
        res = updateProcessorStream(mZslProcessor, params);
        outputStreams.push(getZslStreamId());
    }

    outputStreams.push(getPreviewStreamId());
    if (!params.recordingHint) {
        if (!restart) {
            res = mStreamingProcessor->updatePreviewRequest(params); //根据当前不同模式,调用不容的request,这里调用updatePreviewRequest
        }
        res = mStreamingProcessor->startStream(StreamingProcessor::PREVIEW,
                outputStreams);
    } else {
        if (!restart) {
            res = mStreamingProcessor->updateRecordingRequest(params);
        }
        res = mStreamingProcessor->startStream(StreamingProcessor::RECORD,
                outputStreams);
    }
}

该函数定义在:frameworks/av/services/camera/libcameraservice/api1/client2/StreamingProcessor.cpp
status_t StreamingProcessor::updatePreviewRequest(const Parameters &params) {

    res = params.updateRequest(&mPreviewRequest); //更新参数
    res = mPreviewRequest.update(ANDROID_REQUEST_ID,
            &mPreviewRequestId, 1);


}

文件:frameworks/av/services/camera/libcameraservice/api1/client2/Parameters.cpp

该函数通过:request->update更新现有参数到metadata中,供hal层使用
status_t Parameters::updateRequest(CameraMetadata *request) const {
    camera_metadata_ro_entry_t entry = staticInfo(ANDROID_LED_AVAILABLE_LEDS,0,0,false);
    for(size_t i = 0; i < entry.count; ++i) {
        uint8_t led = entry.data.u8[i];
        switch(led) {
            case ANDROID_LED_AVAILABLE_LEDS_TRANSMIT: {
                uint8_t transmitDefault = ANDROID_LED_TRANSMIT_ON;
                res = request->update(ANDROID_LED_TRANSMIT,
                                      &transmitDefault, 1);
            }
        }
    }

    res = request->update(ANDROID_REQUEST_METADATA_MODE,&metadataMode, 1);

    if (intent.data.u8[0] == ANDROID_CONTROL_CAPTURE_INTENT_STILL_CAPTURE) {
        res = request->update(ANDROID_CONTROL_AE_TARGET_FPS_RANGE, fastInfo.bestStillCaptureFpsRange, 2);
    } else {
        res = request->update(ANDROID_CONTROL_AE_TARGET_FPS_RANGE, previewFpsRange, 2);
    }
    res = request->update(ANDROID_CONTROL_AWB_LOCK, &reqWbLock, 1);
    res = request->update(ANDROID_CONTROL_EFFECT_MODE,&effectMode, 1);
    res = request->update(ANDROID_CONTROL_AE_ANTIBANDING_MODE,&antibandingMode, 1);
    res = request->update(ANDROID_CONTROL_MODE,&reqControlMode, 1);
    res = request->update(ANDROID_CONTROL_SCENE_MODE,&reqSceneMode, 1);
    res = request->update(ANDROID_FLASH_MODE,&reqFlashMode, 1);
    res = request->update(ANDROID_CONTROL_AE_MODE,&reqAeMode, 1);
    res = request->update(ANDROID_CONTROL_AE_LOCK,&reqAeLock, 1);
    res = request->update(ANDROID_CONTROL_AWB_MODE,&wbMode, 1);
    res = request->update(ANDROID_LENS_FOCUS_DISTANCE,&reqFocusDistance, 1);
    res = request->update(ANDROID_CONTROL_AF_MODE,&reqFocusMode, 1);
    res = request->update(ANDROID_CONTROL_AF_REGIONS,reqFocusingAreas, reqFocusingAreasSize);
    res = request->update(ANDROID_CONTROL_AE_EXPOSURE_COMPENSATION,&exposureCompensation, 1);
    res = request->update(ANDROID_CONTROL_AE_REGIONS,reqMeteringAreas, reqMeteringAreasSize);

    if (maxAwbRegions > 0) {
        if (maxAwbRegions >= meteringAreas.size()) {
            res = request->update(ANDROID_CONTROL_AWB_REGIONS,reqMeteringAreas, reqMeteringAreasSize);
        } else {
   res = request->update(ANDROID_CONTROL_AWB_REGIONS,zeroedAwbAreas, sizeof(zeroedAwbAreas)/sizeof(int32_t));
    }
    res = request->update(ANDROID_SCALER_CROP_REGION,reqCropRegion, 4);
    res = request->update(ANDROID_CONTROL_VIDEO_STABILIZATION_MODE,&reqVstabMode, 1);
  res = request->update(ANDROID_STATISTICS_FACE_DETECT_MODE,&reqFaceDetectMode, 1); //更新facedetect参数
}

然后调用到frameworks/av/services/camera/libcameraservice/device3/Camera3Device.cpp
bool Camera3Device::RequestThread::threadLoop() 启动线程.具体调用过程还不清楚,应该是上文中某个updatestream导致线程启动,有知道的小伙伴还望分享一下

然后通过sendRequestsOneByOne下发request请求
bool Camera3Device::RequestThread::sendRequestsOneByOne()  {

    for (auto& nextRequest : mNextRequests) {
       res = mInterface->processCaptureRequest(&nextRequest.halRequest); //调用进入hal层代码
        if (nextRequest.halRequest.settings != NULL) {
            nextRequest.captureRequest->mSettings.unlock(nextRequest.halRequest.settings);
        }
    }
}

HAL3文件:hardware/qcom/camera/QCamera2/HAL3/QCamera3HWI.cpp
int QCamera3HardwareInterface::process_capture_request(
                    const struct camera3_device *device,
                    camera3_capture_request_t *request)
{
    if (pbcr::BcrEnablerHal3::getInstance().processCaptureRequest(ret, device, request)   下发setparameter
        == pbcr::BCR_ENABLER_HANDLED) {
        return ret;
    }
    QCamera3HardwareInterface *hw = reinterpret_cast<QCamera3HardwareInterface *>(device->priv);
    int rc = hw->orchestrateRequest(request);
}

int QCamera3HardwareInterface::processCaptureRequest(
                    camera3_capture_request_t *request,
                    List<InternalRequest> &internallyRequestedStreams)
该函数中调用setFrameParameters来出发hal获取metadata


int QCamera3HardwareInterface::setFrameParameters(
                    camera3_capture_request_t *request,
                    cam_stream_ID_t streamsArray,
                    int blob_request,
                    uint32_t snapshotStreamId)
{
        rc = translateToHalMetadata(request, mParameters, snapshotStreamId);
}

函数int QCamera3HardwareInterface::translateToHalMetadata通过find函数获取当前参数状态
 face_detect为例;                                
    if (frame_settings.exists(ANDROID_STATISTICS_FACE_DETECT_MODE)) {
        uint8_t fwk_facedetectMode = frame_settings.find(ANDROID_STATISTICS_FACE_DETECT_MODE).data.u8[0];

        int val = lookupHalName(FACEDETECT_MODES_MAP, METADATA_MAP_SIZE(FACEDETECT_MODES_MAP),
                fwk_facedetectMode);

        if (NAME_NOT_FOUND != val) {
            uint8_t facedetectMode = (uint8_t)val;
            if (ADD_SET_PARAM_ENTRY_TO_BATCH(hal_metadata, CAM_INTF_META_STATS_FACEDETECT_MODE,
                    facedetectMode)) {
                rc = BAD_VALUE;
            }
        }
    }

至此face_detect的命令就已经下发到hal层中了

 

关于face detect的结果情况反馈给ap
在camera启动的时候就已经启动了一个用于接收request结果的callback函数:
void QCamera3HardwareInterface::captureResultCb(mm_camera_super_buf_t *metadata_buf,
                camera3_stream_buffer_t *buffer, uint32_t frame_number, bool isInputBuffer)
{
    if (metadata_buf) {
        pthread_mutex_lock(&mMutex);
        uint8_t batchSize = mBatchSize;
        pthread_mutex_unlock(&mMutex);
        if (batchSize) {
            handleBatchMetadata(metadata_buf,
                    true /* free_and_bufdone_meta_buf */);
        } else { 
            handleMetadataWithLock(metadata_buf,true,false ,NULL); //用于向hal层更新request结果
        }
    } else if (isInputBuffer) {
        pthread_mutex_lock(&mMutex);
        handleInputBufferWithLock(frame_number);
        pthread_mutex_unlock(&mMutex);
    } else {
        pthread_mutex_lock(&mMutex);
        handleBufferWithLock(buffer, frame_number);
        pthread_mutex_unlock(&mMutex);
    }
    return;
}


在handleMetadataWithLock函数中


result.result = translateFromHalMetadata(metadata,
                    i->timestamp, i->request_id, i->jpegMetadata, i->pipeline_depth,
                    i->capture_intent, internalPproc, i->fwkCacMode,
                    firstMetadataInBatch);

camera_metadata_t* QCamera3HardwareInterface::translateFromHalMetadata(
                                 metadata_buffer_t *metadata,
                                 nsecs_t timestamp,
                                 int32_t request_id,
                                 const CameraMetadata& jpegMetadata,
                                 uint8_t pipeline_depth,
                                 uint8_t capture_intent,
                                 bool pprocDone,
                                 uint8_t fwk_cacMode,
                                 bool firstMetadataInBatch)
{
    camMetadata.update(ANDROID_SENSOR_TIMESTAMP, &timestamp, 1);
    camMetadata.update(ANDROID_REQUEST_ID, &request_id, 1);
    camMetadata.update(ANDROID_REQUEST_PIPELINE_DEPTH, &pipeline_depth, 1);
    camMetadata.update(ANDROID_CONTROL_CAPTURE_INTENT, &capture_intent, 1);
    camMetadata.update(ANDROID_SYNC_FRAME_NUMBER, &fwk_frame_number, 1);
    camMetadata.update(ANDROID_CONTROL_AE_TARGET_FPS_RANGE,fps_range, 2);
    camMetadata.update(ANDROID_CONTROL_AE_EXPOSURE_COMPENSATION, expCompensation, 1);
    camMetadata.update(ANDROID_CONTROL_SCENE_MODE, &fwkSceneMode, 1);
    camMetadata.update(ANDROID_CONTROL_AE_LOCK, &fwk_ae_lock, 1);
    camMetadata.update(ANDROID_CONTROL_AWB_LOCK, &fwk_awb_lock, 1);
    camMetadata.update(ANDROID_COLOR_CORRECTION_MODE, &fwk_color_correct_mode, 1);
    camMetadata.update(ANDROID_EDGE_MODE, &(edgeApplication->edge_mode), 1);
    camMetadata.update(ANDROID_FLASH_FIRING_POWER, &fwk_flashPower, 1);
    camMetadata.update(ANDROID_FLASH_FIRING_TIME, flashFiringTime, 1);
    camMetadata.update(ANDROID_FLASH_STATE, &fwk_flashState, 1);
    camMetadata.update(ANDROID_FLASH_MODE, &fwk_flashMode, 1);
    camMetadata.update(ANDROID_HOT_PIXEL_MODE, &fwk_hotPixelMode, 1);
    camMetadata.update(ANDROID_LENS_APERTURE , lensAperture, 1);
    camMetadata.update(ANDROID_LENS_FILTER_DENSITY , filterDensity, 1);
    camMetadata.update(ANDROID_LENS_FOCAL_LENGTH, focalLength, 1);
    camMetadata.update(ANDROID_LENS_OPTICAL_STABILIZATION_MODE, &fwk_opticalStab, 1);
     camMetadata.update(ANDROID_CONTROL_VIDEO_STABILIZATION_MODE, &fwk_videoStab, 1);
     camMetadata.update(ANDROID_NOISE_REDUCTION_MODE, &fwk_noiseRedMode, 1);
     camMetadata.update(ANDROID_REPROCESS_EFFECTIVE_EXPOSURE_FACTOR, effectiveExposureFactor, 1);
     camMetadata.update(QCAMERA3_SENSOR_DYNAMIC_BLACK_LEVEL_PATTERN, fwk_blackLevelInd, 4);
     camMetadata.update(ANDROID_SCALER_CROP_REGION, scalerCropRegion, 4);
     camMetadata.update(ANDROID_SENSOR_EXPOSURE_TIME , sensorExpTime, 1);
     camMetadata.update(ANDROID_SENSOR_FRAME_DURATION, sensorFameDuration, 1);
     camMetadata.update(ANDROID_SENSOR_ROLLING_SHUTTER_SKEW,sensorRollingShutterSkew, 1);
     camMetadata.update(ANDROID_SENSOR_SENSITIVITY, sensorSensitivity, 1);
 camMetadata.update(ANDROID_SENSOR_NOISE_PROFILE, noise_profile,(size_t) (2 * gCamCapability[mCameraId]->num_color_channels));
     camMetadata.update(ANDROID_SHADING_MODE, &fwk_shadingMode, 1);
     camMetadata.update(ANDROID_STATISTICS_FACE_DETECT_MODE, &fwk_faceDetectMode, 1);
     camMetadata.update(ANDROID_STATISTICS_FACE_SCORES, faceScores,numFaces);
     camMetadata.update(ANDROID_STATISTICS_FACE_RECTANGLES,faceRectangles, numFaces * 4U);
  camMetadata.update(ANDROID_STATISTICS_FACE_IDS, faceIds, numFaces);
     camMetadata.update(ANDROID_STATISTICS_FACE_LANDMARKS,faceLandmarks, numFaces * 6U); //更新facedetect结果参数,包含人脸个数,位置等信息
     camMetadata.update(QCAMERA3_STATS_BLINK_DETECTED,detected, numFaces);
     camMetadata.update(QCAMERA3_STATS_BLINK_DEGREE,degree, numFaces * 2);
  camMetadata.update(QCAMERA3_STATS_SMILE_DEGREE,degree, numFaces);
     camMetadata.update(QCAMERA3_STATS_SMILE_CONFIDENCE,confidence, numFaces);
     camMetadata.update(QCAMERA3_STATS_GAZE_ANGLE,(uint8_t *)angle, numFaces);
     camMetadata.update(QCAMERA3_STATS_GAZE_DIRECTION,direction, numFaces * 3);
     camMetadata.update(QCAMERA3_STATS_GAZE_DEGREE,(uint8_t *)degree, numFaces * 2);

这里参数更新以后framwork会在frameworks/av/services/camera/libcameraservice/api1/client2/FrameProcessor.cpp文件中获取对应参数

status_t FrameProcessor::processFaceDetect(const CameraMetadata &frame,
        const sp<Camera2Client> &client)

这里数据就到了framwork,具体的后续数据流程还要进一步梳理
---------------------
作者:wing12345678910
来源:CSDN
原文:https://blog.csdn.net/wing12345678910/article/details/80384326
版权声明:本文为博主原创文章,转载请附上博文链接!

posted @ 2019-05-14 14:41  zzzxzzz  阅读(405)  评论(0)    收藏  举报