diff options
Diffstat (limited to 'camera/OMXCameraAdapter/OMXFD.cpp')
-rw-r--r-- | camera/OMXCameraAdapter/OMXFD.cpp | 504 |
1 files changed, 0 insertions, 504 deletions
diff --git a/camera/OMXCameraAdapter/OMXFD.cpp b/camera/OMXCameraAdapter/OMXFD.cpp deleted file mode 100644 index 9220008..0000000 --- a/camera/OMXCameraAdapter/OMXFD.cpp +++ /dev/null @@ -1,504 +0,0 @@ -/* - * Copyright (C) Texas Instruments - http://www.ti.com/ - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** -* @file OMXFD.cpp -* -* This file contains functionality for handling face detection. -* -*/ - -#include "CameraHal.h" -#include "OMXCameraAdapter.h" - -namespace Ti { -namespace Camera { - -const uint32_t OMXCameraAdapter::FACE_DETECTION_THRESHOLD = 80; - -status_t OMXCameraAdapter::setParametersFD(const android::CameraParameters ¶ms, - BaseCameraAdapter::AdapterState state) -{ - status_t ret = NO_ERROR; - - LOG_FUNCTION_NAME; - - LOG_FUNCTION_NAME_EXIT; - - return ret; -} - -status_t OMXCameraAdapter::startFaceDetection() -{ - status_t ret = NO_ERROR; - - android::AutoMutex lock(mFaceDetectionLock); - - ret = setFaceDetection(true, mFaceOrientation); - if (ret != NO_ERROR) { - goto out; - } - - if ( mFaceDetectionRunning ) { - mFDSwitchAlgoPriority = true; - } - - // Note: White balance will not be face prioritized, since - // the algorithm needs full frame statistics, and not face - // regions alone. - - faceDetectionNumFacesLastOutput = 0; - out: - return ret; -} - -status_t OMXCameraAdapter::stopFaceDetection() -{ - status_t ret = NO_ERROR; - const char *str = NULL; - BaseCameraAdapter::AdapterState state; - BaseCameraAdapter::getState(state); - - android::AutoMutex lock(mFaceDetectionLock); - - ret = setFaceDetection(false, mFaceOrientation); - if (ret != NO_ERROR) { - goto out; - } - - if ( mFaceDetectionRunning ) { - //Enable region priority and disable face priority for AF - setAlgoPriority(REGION_PRIORITY, FOCUS_ALGO, true); - setAlgoPriority(FACE_PRIORITY, FOCUS_ALGO , false); - - //Enable Region priority and disable Face priority - setAlgoPriority(REGION_PRIORITY, EXPOSURE_ALGO, true); - setAlgoPriority(FACE_PRIORITY, EXPOSURE_ALGO, false); - } - - if (mPending3Asettings) { - apply3Asettings(mParameters3A); - } - - faceDetectionNumFacesLastOutput = 0; - out: - return ret; -} - -void OMXCameraAdapter::pauseFaceDetection(bool pause) -{ - android::AutoMutex lock(mFaceDetectionLock); - // pausing will only take affect if fd is already running - if (mFaceDetectionRunning) { - mFaceDetectionPaused = pause; - faceDetectionNumFacesLastOutput = 0; - } -} - -status_t OMXCameraAdapter::setFaceDetectionOrientation(OMX_U32 orientation) -{ - status_t ret = NO_ERROR; - - android::AutoMutex lock(mFaceDetectionLock); - - mFaceOrientation = orientation; - - if (mFaceDetectionRunning) { - // restart face detection with new rotation - setFaceDetection(true, orientation); - } - - return ret; -} - -status_t OMXCameraAdapter::setFaceDetection(bool enable, OMX_U32 orientation) -{ - status_t ret = NO_ERROR; - OMX_ERRORTYPE eError = OMX_ErrorNone; - OMX_CONFIG_OBJDETECTIONTYPE objDetection; - - LOG_FUNCTION_NAME; - - if ( OMX_StateInvalid == mComponentState ) - { - CAMHAL_LOGEA("OMX component is in invalid state"); - ret = -EINVAL; - } - - if ( NO_ERROR == ret ) - { - if ( orientation > 270 ) { - orientation = 0; - } - - OMX_INIT_STRUCT_PTR (&objDetection, OMX_CONFIG_OBJDETECTIONTYPE); - objDetection.nPortIndex = mCameraAdapterParameters.mPrevPortIndex; - objDetection.nDeviceOrientation = orientation; - if ( enable ) - { - objDetection.bEnable = OMX_TRUE; - } - else - { - objDetection.bEnable = OMX_FALSE; - } - - eError = OMX_SetConfig(mCameraAdapterParameters.mHandleComp, - ( OMX_INDEXTYPE ) OMX_IndexConfigImageFaceDetection, - &objDetection); - if ( OMX_ErrorNone != eError ) - { - CAMHAL_LOGEB("Error while configuring face detection 0x%x", eError); - ret = -1; - } - else - { - CAMHAL_LOGDA("Face detection configured successfully"); - } - } - - if ( NO_ERROR == ret ) - { - // TODO(XXX): Should enable/disable FD extra data separately - // on each port. - ret = setExtraData(enable, OMX_ALL, OMX_FaceDetection); - - if ( NO_ERROR != ret ) - { - CAMHAL_LOGEA("Error while configuring face detection extra data"); - } - else - { - CAMHAL_LOGDA("Face detection extra data configured successfully"); - } - } - - if ( NO_ERROR == ret ) - { - mFaceDetectionRunning = enable; - mFaceDetectionPaused = !enable; - } - - LOG_FUNCTION_NAME_EXIT; - - return ret; -} - -status_t OMXCameraAdapter::createPreviewMetadata(OMX_BUFFERHEADERTYPE* pBuffHeader, - android::sp<CameraMetadataResult> &result, - size_t previewWidth, - size_t previewHeight) -{ - status_t ret = NO_ERROR; - status_t faceRet = NO_ERROR; - status_t metaRet = NO_ERROR; - OMX_FACEDETECTIONTYPE *faceData = NULL; - - LOG_FUNCTION_NAME; - - if ( OMX_StateExecuting != mComponentState ) { - CAMHAL_LOGEA("OMX component is not in executing state"); - return NO_INIT; - } - - if ( NULL == pBuffHeader ) { - CAMHAL_LOGEA("Invalid Buffer header"); - return-EINVAL; - } - - if ( mFaceDetectionRunning && !mFaceDetectionPaused ) { - OMX_OTHER_EXTRADATATYPE *extraData; - - extraData = getExtradata(pBuffHeader->pPlatformPrivate, - (OMX_EXTRADATATYPE)OMX_FaceDetection); - - if ( NULL != extraData ) { - CAMHAL_LOGSVB("Size = %d, sizeof = %d, eType = 0x%x, nDataSize= %d, nPortIndex = 0x%x, nVersion = 0x%x", - extraData->nSize, - sizeof(OMX_OTHER_EXTRADATATYPE), - extraData->eType, - extraData->nDataSize, - extraData->nPortIndex, - extraData->nVersion); - } else { - CAMHAL_LOGD("FD extra data not found!"); - return -EINVAL; - } - - faceData = ( OMX_FACEDETECTIONTYPE * ) extraData->data; - if ( NULL != faceData ) { - if ( sizeof(OMX_FACEDETECTIONTYPE) == faceData->nSize ) { - CAMHAL_LOGSVB("Faces detected %d", - faceData->ulFaceCount, - faceData->nSize, - sizeof(OMX_FACEDETECTIONTYPE), - faceData->eCameraView, - faceData->nPortIndex, - faceData->nVersion); - } else { - CAMHAL_LOGEB("OMX_FACEDETECTIONTYPE size mismatch: expected = %d, received = %d", - ( unsigned int ) sizeof(OMX_FACEDETECTIONTYPE), - ( unsigned int ) faceData->nSize); - return -EINVAL; - } - } else { - CAMHAL_LOGEA("Invalid OMX_FACEDETECTIONTYPE"); - return -EINVAL; - } - } - - result = new (std::nothrow) CameraMetadataResult; - if(NULL == result.get()) { - ret = NO_MEMORY; - return ret; - } - - //Encode face coordinates - faceRet = encodeFaceCoordinates(faceData, result->getMetadataResult() - , previewWidth, previewHeight); - if ((NO_ERROR == faceRet) || (NOT_ENOUGH_DATA == faceRet)) { - // Ignore harmless errors (no error and no update) and go ahead and encode - // the preview meta data - metaRet = encodePreviewMetadata(result->getMetadataResult() - , pBuffHeader->pPlatformPrivate); - if ( (NO_ERROR != metaRet) && (NOT_ENOUGH_DATA != metaRet) ) { - // Some 'real' error occurred during preview meta data encod, clear metadata - // result and return correct error code - result.clear(); - ret = metaRet; - } - } else { - //Some real error occurred during face encoding, clear metadata result - // and return correct error code - result.clear(); - ret = faceRet; - } - - if((NOT_ENOUGH_DATA == faceRet) && (NOT_ENOUGH_DATA == metaRet)) { - //No point sending the callback if nothing is changed - result.clear(); - ret = faceRet; - } - - LOG_FUNCTION_NAME_EXIT; - - return ret; -} - -status_t OMXCameraAdapter::encodeFaceCoordinates(const OMX_FACEDETECTIONTYPE *faceData, - camera_frame_metadata_t *metadataResult, - size_t previewWidth, - size_t previewHeight) -{ - status_t ret = NO_ERROR; - camera_face_t *faces; - size_t hRange, vRange; - double tmp; - bool faceArrayChanged = false; - - LOG_FUNCTION_NAME; - - hRange = CameraMetadataResult::RIGHT - CameraMetadataResult::LEFT; - vRange = CameraMetadataResult::BOTTOM - CameraMetadataResult::TOP; - - android::AutoMutex lock(mFaceDetectionLock); - - // Avoid memory leak if called twice on same CameraMetadataResult - if ( (0 < metadataResult->number_of_faces) && (NULL != metadataResult->faces) ) { - free(metadataResult->faces); - metadataResult->number_of_faces = 0; - metadataResult->faces = NULL; - } - - if ( (NULL != faceData) && (0 < faceData->ulFaceCount) ) { - int orient_mult; - int trans_left, trans_top, trans_right, trans_bot; - - faces = ( camera_face_t * ) malloc(sizeof(camera_face_t)*faceData->ulFaceCount); - if ( NULL == faces ) { - ret = NO_MEMORY; - goto out; - } - - /** - / * When device is 180 degrees oriented to the sensor, need to translate - / * the output from Ducati to what Android expects - / * Ducati always gives face coordinates in this form, irrespective of - / * rotation, i.e (l,t) always represents the point towards the left eye - / * and top of hair. - / * (l, t) - / * --------------- - / * - ,,,,,,, - - / * - | | - - / * - |<a <a| - - / * - (| ^ |) - - / * - | -=- | - - / * - \_____/ - - / * --------------- - / * (r, b) - / * - / * However, Android expects the coords to be in respect with what the - / * sensor is viewing, i.e Android expects sensor to see this with (l,t) - / * and (r,b) like so: - / * (l, t) - / * --------------- - / * - _____ - - / * - / \ - - / * - | -=- | - - / * - (| ^ |) - - / * - |a> a>| - - / * - | | - - / * - ,,,,,,, - - / * --------------- - / * (r, b) - */ - - if (mFaceOrientation == 180) { - orient_mult = -1; - trans_left = 2; // right is now left - trans_top = 3; // bottom is now top - trans_right = 0; // left is now right - trans_bot = 1; // top is not bottom - } else { - orient_mult = 1; - trans_left = 0; // left - trans_top = 1; // top - trans_right = 2; // right - trans_bot = 3; // bottom - } - - int j = 0, i = 0; - for ( ; j < faceData->ulFaceCount ; j++) - { - OMX_S32 nLeft = 0; - OMX_S32 nTop = 0; - //Face filtering - //For real faces, it is seen that the h/w passes a score >=80 - //For false faces, we seem to get even a score of 70 sometimes. - //In order to avoid any issue at application level, we filter - //<=70 score here. - if(faceData->tFacePosition[j].nScore <= FACE_DETECTION_THRESHOLD) - continue; - - if (mFaceOrientation == 180) { - // from sensor pov, the left pos is the right corner of the face in pov of frame - nLeft = faceData->tFacePosition[j].nLeft + faceData->tFacePosition[j].nWidth; - nTop = faceData->tFacePosition[j].nTop + faceData->tFacePosition[j].nHeight; - } else { - nLeft = faceData->tFacePosition[j].nLeft; - nTop = faceData->tFacePosition[j].nTop; - } - - tmp = ( double ) nLeft / ( double ) previewWidth; - tmp *= hRange; - tmp -= hRange/2; - faces[i].rect[trans_left] = tmp; - - tmp = ( double ) nTop / ( double )previewHeight; - tmp *= vRange; - tmp -= vRange/2; - faces[i].rect[trans_top] = tmp; - - tmp = ( double ) faceData->tFacePosition[j].nWidth / ( double ) previewWidth; - tmp *= hRange; - tmp *= orient_mult; - faces[i].rect[trans_right] = faces[i].rect[trans_left] + tmp; - - tmp = ( double ) faceData->tFacePosition[j].nHeight / ( double ) previewHeight; - tmp *= vRange; - tmp *= orient_mult; - faces[i].rect[trans_bot] = faces[i].rect[trans_top] + tmp; - - faces[i].score = faceData->tFacePosition[j].nScore; - faces[i].id = 0; - faces[i].left_eye[0] = CameraMetadataResult::INVALID_DATA; - faces[i].left_eye[1] = CameraMetadataResult::INVALID_DATA; - faces[i].right_eye[0] = CameraMetadataResult::INVALID_DATA; - faces[i].right_eye[1] = CameraMetadataResult::INVALID_DATA; - faces[i].mouth[0] = CameraMetadataResult::INVALID_DATA; - faces[i].mouth[1] = CameraMetadataResult::INVALID_DATA; - i++; - } - - metadataResult->number_of_faces = i; - metadataResult->faces = faces; - - for (int i = 0; i < metadataResult->number_of_faces; i++) - { - bool faceChanged = true; - int centerX = (faces[i].rect[trans_left] + faces[i].rect[trans_right] ) / 2; - int centerY = (faces[i].rect[trans_top] + faces[i].rect[trans_bot] ) / 2; - - int sizeX = (faces[i].rect[trans_right] - faces[i].rect[trans_left] ) ; - int sizeY = (faces[i].rect[trans_bot] - faces[i].rect[trans_top] ) ; - - for (int j = 0; j < faceDetectionNumFacesLastOutput; j++) - { - int tempCenterX = (faceDetectionLastOutput[j].rect[trans_left] + - faceDetectionLastOutput[j].rect[trans_right] ) / 2; - int tempCenterY = (faceDetectionLastOutput[j].rect[trans_top] + - faceDetectionLastOutput[j].rect[trans_bot] ) / 2; - int tempSizeX = (faceDetectionLastOutput[j].rect[trans_right] - - faceDetectionLastOutput[j].rect[trans_left] ) ; - int tempSizeY = (faceDetectionLastOutput[j].rect[trans_bot] - - faceDetectionLastOutput[j].rect[trans_top] ) ; - - if ( ( tempCenterX == centerX) && - ( tempCenterY == centerY) ) { - // Found Face. - // Now check size of rectangle - // compare to last output. - if ( ( tempSizeX == sizeX ) && - ( tempSizeY == sizeY ) ) { - faceChanged = false; - } - } - } - // Send face detection data after some face coordinate changes - if (faceChanged) { - faceArrayChanged = true; - } - } - - // Save this output for next iteration - for (int i = 0; i < metadataResult->number_of_faces; i++) - { - faceDetectionLastOutput[i] = faces[i]; - } - } else { - metadataResult->number_of_faces = 0; - metadataResult->faces = NULL; - } - - // Send face detection data after face count changes - if (faceDetectionNumFacesLastOutput != metadataResult->number_of_faces) { - faceArrayChanged = true; - } - faceDetectionNumFacesLastOutput = metadataResult->number_of_faces; - - if ( !faceArrayChanged ) { - ret = NOT_ENOUGH_DATA; - } - - LOG_FUNCTION_NAME_EXIT; - -out: - - return ret; -} - -} // namespace Camera -} // namespace Ti |