summaryrefslogtreecommitdiffstats
path: root/camera/OMXCameraAdapter/OMXFD.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'camera/OMXCameraAdapter/OMXFD.cpp')
-rw-r--r--camera/OMXCameraAdapter/OMXFD.cpp504
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 &params,
- 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