OMXFD.cpp revision 82640237cf0ca200932a66777fd1907d66cd0322
1c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev/* 2c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev * Copyright (C) Texas Instruments - http://www.ti.com/ 3c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev * 4c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev * Licensed under the Apache License, Version 2.0 (the "License"); 5c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev * you may not use this file except in compliance with the License. 6c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev * You may obtain a copy of the License at 7c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev * 8c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev * http://www.apache.org/licenses/LICENSE-2.0 9c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev * 10c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev * Unless required by applicable law or agreed to in writing, software 11c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev * distributed under the License is distributed on an "AS IS" BASIS, 12c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev * See the License for the specific language governing permissions and 14c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev * limitations under the License. 15c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev */ 16c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 17c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev/** 18c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev* @file OMXFD.cpp 19c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev* 20c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev* This file contains functionality for handling face detection. 21c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev* 22c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev*/ 23c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 24c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev#undef LOG_TAG 25c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 26c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev#define LOG_TAG "CameraHAL" 27c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 28c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev#include "CameraHal.h" 29c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev#include "OMXCameraAdapter.h" 30c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 31967f1197f015b6d2f3b34e60fa787f7066efb824Sundar Raman#define FACE_DETECTION_THRESHOLD 80 32967f1197f015b6d2f3b34e60fa787f7066efb824Sundar Raman 337762bf32b7bd874ce34948eb53a3bfa3906f4aefTyler Luu// constants used for face smooth filtering 347762bf32b7bd874ce34948eb53a3bfa3906f4aefTyler Luustatic const int HorizontalFilterThreshold = 40; 357762bf32b7bd874ce34948eb53a3bfa3906f4aefTyler Luustatic const int VerticalFilterThreshold = 40; 367762bf32b7bd874ce34948eb53a3bfa3906f4aefTyler Luustatic const int HorizontalFaceSizeThreshold = 30; 377762bf32b7bd874ce34948eb53a3bfa3906f4aefTyler Luustatic const int VerticalFaceSizeThreshold = 30; 387762bf32b7bd874ce34948eb53a3bfa3906f4aefTyler Luu 397762bf32b7bd874ce34948eb53a3bfa3906f4aefTyler Luu 40c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchevnamespace android { 41c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 42c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchevstatus_t OMXCameraAdapter::setParametersFD(const CameraParameters ¶ms, 43c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev BaseCameraAdapter::AdapterState state) 44c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev{ 45c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev status_t ret = NO_ERROR; 46c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 47c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev LOG_FUNCTION_NAME; 48c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 49c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev LOG_FUNCTION_NAME_EXIT; 50c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 51c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev return ret; 52c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev} 53c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 54c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchevstatus_t OMXCameraAdapter::startFaceDetection() 55c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev{ 56c0fc811b503ef0c0ccd024f77f9ac7d6972f77c8Sundar Raman status_t ret = NO_ERROR; 57c0fc811b503ef0c0ccd024f77f9ac7d6972f77c8Sundar Raman 58c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev Mutex::Autolock lock(mFaceDetectionLock); 59c0fc811b503ef0c0ccd024f77f9ac7d6972f77c8Sundar Raman 60c0fc811b503ef0c0ccd024f77f9ac7d6972f77c8Sundar Raman ret = setFaceDetection(true, mDeviceOrientation); 61c0fc811b503ef0c0ccd024f77f9ac7d6972f77c8Sundar Raman if (ret != NO_ERROR) { 62c0fc811b503ef0c0ccd024f77f9ac7d6972f77c8Sundar Raman goto out; 63c0fc811b503ef0c0ccd024f77f9ac7d6972f77c8Sundar Raman } 64c0fc811b503ef0c0ccd024f77f9ac7d6972f77c8Sundar Raman 6561db8718454958a21d5b31282027db01a5c0de63Milen Mitkov if ( mFaceDetectionRunning ) 6661db8718454958a21d5b31282027db01a5c0de63Milen Mitkov { 6761db8718454958a21d5b31282027db01a5c0de63Milen Mitkov //Disable region priority and enable face priority for AF 6861db8718454958a21d5b31282027db01a5c0de63Milen Mitkov setAlgoPriority(REGION_PRIORITY, FOCUS_ALGO, false); 6961db8718454958a21d5b31282027db01a5c0de63Milen Mitkov setAlgoPriority(FACE_PRIORITY, FOCUS_ALGO , true); 7061db8718454958a21d5b31282027db01a5c0de63Milen Mitkov 7161db8718454958a21d5b31282027db01a5c0de63Milen Mitkov //Disable Region priority and enable Face priority 7261db8718454958a21d5b31282027db01a5c0de63Milen Mitkov setAlgoPriority(REGION_PRIORITY, EXPOSURE_ALGO, false); 7361db8718454958a21d5b31282027db01a5c0de63Milen Mitkov setAlgoPriority(FACE_PRIORITY, EXPOSURE_ALGO, true); 7461db8718454958a21d5b31282027db01a5c0de63Milen Mitkov } 75c0fc811b503ef0c0ccd024f77f9ac7d6972f77c8Sundar Raman 767762bf32b7bd874ce34948eb53a3bfa3906f4aefTyler Luu // Note: White balance will not be face prioritized, since 777762bf32b7bd874ce34948eb53a3bfa3906f4aefTyler Luu // the algorithm needs full frame statistics, and not face 787762bf32b7bd874ce34948eb53a3bfa3906f4aefTyler Luu // regions alone. 79c0fc811b503ef0c0ccd024f77f9ac7d6972f77c8Sundar Raman 807762bf32b7bd874ce34948eb53a3bfa3906f4aefTyler Luu faceDetectionNumFacesLastOutput = 0; 81c0fc811b503ef0c0ccd024f77f9ac7d6972f77c8Sundar Raman out: 82c0fc811b503ef0c0ccd024f77f9ac7d6972f77c8Sundar Raman return ret; 83c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev} 84c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 85c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchevstatus_t OMXCameraAdapter::stopFaceDetection() 86c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev{ 87c0fc811b503ef0c0ccd024f77f9ac7d6972f77c8Sundar Raman status_t ret = NO_ERROR; 88c0fc811b503ef0c0ccd024f77f9ac7d6972f77c8Sundar Raman const char *str = NULL; 89c0fc811b503ef0c0ccd024f77f9ac7d6972f77c8Sundar Raman BaseCameraAdapter::AdapterState state; 90c0fc811b503ef0c0ccd024f77f9ac7d6972f77c8Sundar Raman BaseCameraAdapter::getState(state); 91c0fc811b503ef0c0ccd024f77f9ac7d6972f77c8Sundar Raman 92c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev Mutex::Autolock lock(mFaceDetectionLock); 93c0fc811b503ef0c0ccd024f77f9ac7d6972f77c8Sundar Raman 94c0fc811b503ef0c0ccd024f77f9ac7d6972f77c8Sundar Raman ret = setFaceDetection(false, mDeviceOrientation); 95c0fc811b503ef0c0ccd024f77f9ac7d6972f77c8Sundar Raman if (ret != NO_ERROR) { 96c0fc811b503ef0c0ccd024f77f9ac7d6972f77c8Sundar Raman goto out; 97c0fc811b503ef0c0ccd024f77f9ac7d6972f77c8Sundar Raman } 98c0fc811b503ef0c0ccd024f77f9ac7d6972f77c8Sundar Raman 99c0fc811b503ef0c0ccd024f77f9ac7d6972f77c8Sundar Raman // Reset 3A settings 100c0fc811b503ef0c0ccd024f77f9ac7d6972f77c8Sundar Raman ret = setParameters3A(mParams, state); 101c0fc811b503ef0c0ccd024f77f9ac7d6972f77c8Sundar Raman if (ret != NO_ERROR) { 102c0fc811b503ef0c0ccd024f77f9ac7d6972f77c8Sundar Raman goto out; 103c0fc811b503ef0c0ccd024f77f9ac7d6972f77c8Sundar Raman } 104c0fc811b503ef0c0ccd024f77f9ac7d6972f77c8Sundar Raman 105c0fc811b503ef0c0ccd024f77f9ac7d6972f77c8Sundar Raman if (mPending3Asettings) { 106c0fc811b503ef0c0ccd024f77f9ac7d6972f77c8Sundar Raman apply3Asettings(mParameters3A); 107c0fc811b503ef0c0ccd024f77f9ac7d6972f77c8Sundar Raman } 108c0fc811b503ef0c0ccd024f77f9ac7d6972f77c8Sundar Raman 1097762bf32b7bd874ce34948eb53a3bfa3906f4aefTyler Luu faceDetectionNumFacesLastOutput = 0; 110c0fc811b503ef0c0ccd024f77f9ac7d6972f77c8Sundar Raman out: 111c0fc811b503ef0c0ccd024f77f9ac7d6972f77c8Sundar Raman return ret; 112c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev} 113c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 114aa6e62e279cb54ae76c55ba9f8d02da230ce34e7Tyler Luuvoid OMXCameraAdapter::pauseFaceDetection(bool pause) 115aa6e62e279cb54ae76c55ba9f8d02da230ce34e7Tyler Luu{ 116aa6e62e279cb54ae76c55ba9f8d02da230ce34e7Tyler Luu Mutex::Autolock lock(mFaceDetectionLock); 117aa6e62e279cb54ae76c55ba9f8d02da230ce34e7Tyler Luu // pausing will only take affect if fd is already running 118aa6e62e279cb54ae76c55ba9f8d02da230ce34e7Tyler Luu if (mFaceDetectionRunning) { 119aa6e62e279cb54ae76c55ba9f8d02da230ce34e7Tyler Luu mFaceDetectionPaused = pause; 1207762bf32b7bd874ce34948eb53a3bfa3906f4aefTyler Luu faceDetectionNumFacesLastOutput = 0; 121aa6e62e279cb54ae76c55ba9f8d02da230ce34e7Tyler Luu } 122aa6e62e279cb54ae76c55ba9f8d02da230ce34e7Tyler Luu} 123aa6e62e279cb54ae76c55ba9f8d02da230ce34e7Tyler Luu 124c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchevstatus_t OMXCameraAdapter::setFaceDetection(bool enable, OMX_U32 orientation) 125c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev{ 126c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev status_t ret = NO_ERROR; 127c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev OMX_ERRORTYPE eError = OMX_ErrorNone; 128c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev OMX_CONFIG_OBJDETECTIONTYPE objDetection; 129c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 130c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev LOG_FUNCTION_NAME; 131c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 132c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev if ( OMX_StateInvalid == mComponentState ) 133c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev { 134c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev CAMHAL_LOGEA("OMX component is in invalid state"); 135c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev ret = -EINVAL; 136c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev } 137c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 138c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev if ( NO_ERROR == ret ) 139c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev { 1407762bf32b7bd874ce34948eb53a3bfa3906f4aefTyler Luu if ( orientation > 270 ) { 141c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev orientation = 0; 142c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev } 143c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 144c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev OMX_INIT_STRUCT_PTR (&objDetection, OMX_CONFIG_OBJDETECTIONTYPE); 145c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev objDetection.nPortIndex = mCameraAdapterParameters.mPrevPortIndex; 146c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev objDetection.nDeviceOrientation = orientation; 147c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev if ( enable ) 148c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev { 149c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev objDetection.bEnable = OMX_TRUE; 150c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev } 151c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev else 152c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev { 153c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev objDetection.bEnable = OMX_FALSE; 154c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev } 155c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 156c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev eError = OMX_SetConfig(mCameraAdapterParameters.mHandleComp, 157c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev ( OMX_INDEXTYPE ) OMX_IndexConfigImageFaceDetection, 158c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev &objDetection); 159c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev if ( OMX_ErrorNone != eError ) 160c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev { 161c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev CAMHAL_LOGEB("Error while configuring face detection 0x%x", eError); 162c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev ret = -1; 163c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev } 164c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev else 165c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev { 166c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev CAMHAL_LOGDA("Face detection configured successfully"); 167c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev } 168c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev } 169c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 170c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev if ( NO_ERROR == ret ) 171c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev { 172ef73bec8a83a2fd7fbb072d009382c64eb2da0eeTyler Luu ret = setExtraData(enable, mCameraAdapterParameters.mPrevPortIndex, OMX_FaceDetection); 173c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 174ef73bec8a83a2fd7fbb072d009382c64eb2da0eeTyler Luu if ( NO_ERROR != ret ) 175c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev { 176ef73bec8a83a2fd7fbb072d009382c64eb2da0eeTyler Luu CAMHAL_LOGEA("Error while configuring face detection extra data"); 177c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev } 178c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev else 179c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev { 180c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev CAMHAL_LOGDA("Face detection extra data configured successfully"); 181c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev } 182c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev } 183c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 184c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev if ( NO_ERROR == ret ) 185c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev { 186c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev mFaceDetectionRunning = enable; 187aa6e62e279cb54ae76c55ba9f8d02da230ce34e7Tyler Luu mFaceDetectionPaused = !enable; 188c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev } 189c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 190c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev LOG_FUNCTION_NAME_EXIT; 191c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 192c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev return ret; 193c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev} 194c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 195c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchevstatus_t OMXCameraAdapter::detectFaces(OMX_BUFFERHEADERTYPE* pBuffHeader, 196c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev sp<CameraFDResult> &result, 197c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev size_t previewWidth, 198c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev size_t previewHeight) 199c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev{ 200c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev status_t ret = NO_ERROR; 201c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev OMX_ERRORTYPE eError = OMX_ErrorNone; 202c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev OMX_TI_FACERESULT *faceResult; 203c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev OMX_OTHER_EXTRADATATYPE *extraData; 204c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev OMX_FACEDETECTIONTYPE *faceData; 205c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev OMX_TI_PLATFORMPRIVATE *platformPrivate; 206c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev camera_frame_metadata_t *faces; 207c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 208c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev LOG_FUNCTION_NAME; 209c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 210c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev if ( OMX_StateExecuting != mComponentState ) { 211c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev CAMHAL_LOGEA("OMX component is not in executing state"); 212c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev return NO_INIT; 213c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev } 214c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 215c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev if ( NULL == pBuffHeader ) { 216c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev CAMHAL_LOGEA("Invalid Buffer header"); 217c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev return-EINVAL; 218c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev } 219c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 220c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev platformPrivate = (OMX_TI_PLATFORMPRIVATE *) (pBuffHeader->pPlatformPrivate); 221c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev if ( NULL != platformPrivate ) { 222c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev if ( sizeof(OMX_TI_PLATFORMPRIVATE) == platformPrivate->nSize ) { 223c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev CAMHAL_LOGVB("Size = %d, sizeof = %d, pAuxBuf = 0x%x, pAuxBufSize= %d, pMetaDataBufer = 0x%x, nMetaDataSize = %d", 224c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev platformPrivate->nSize, 225c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev sizeof(OMX_TI_PLATFORMPRIVATE), 226c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev platformPrivate->pAuxBuf1, 227c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev platformPrivate->pAuxBufSize1, 228c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev platformPrivate->pMetaDataBuffer, 229c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev platformPrivate->nMetaDataSize); 230c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev } else { 231c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev CAMHAL_LOGEB("OMX_TI_PLATFORMPRIVATE size mismatch: expected = %d, received = %d", 232c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev ( unsigned int ) sizeof(OMX_TI_PLATFORMPRIVATE), 233c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev ( unsigned int ) platformPrivate->nSize); 23482640237cf0ca200932a66777fd1907d66cd0322Akwasi Boateng return -EINVAL; 235c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev } 236c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev } else { 237c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev CAMHAL_LOGEA("Invalid OMX_TI_PLATFORMPRIVATE"); 238c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev return-EINVAL; 239c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev } 240c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 241c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 242c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev if ( 0 >= platformPrivate->nMetaDataSize ) { 243c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev CAMHAL_LOGEB("OMX_TI_PLATFORMPRIVATE nMetaDataSize is size is %d", 244c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev ( unsigned int ) platformPrivate->nMetaDataSize); 245c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev return -EINVAL; 246c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev } 247c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 248cf0a61f13533d70cb7ad700330de94142c2afe6aMilen Mitkov extraData = getExtradata((OMX_OTHER_EXTRADATATYPE *) (platformPrivate->pMetaDataBuffer), 249cf0a61f13533d70cb7ad700330de94142c2afe6aMilen Mitkov (OMX_EXTRADATATYPE)OMX_FaceDetection); 250cf0a61f13533d70cb7ad700330de94142c2afe6aMilen Mitkov 251c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev if ( NULL != extraData ) { 252c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev CAMHAL_LOGVB("Size = %d, sizeof = %d, eType = 0x%x, nDataSize= %d, nPortIndex = 0x%x, nVersion = 0x%x", 253c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev extraData->nSize, 254c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev sizeof(OMX_OTHER_EXTRADATATYPE), 255c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev extraData->eType, 256c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev extraData->nDataSize, 257c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev extraData->nPortIndex, 258c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev extraData->nVersion); 259c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev } else { 260c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev CAMHAL_LOGEA("Invalid OMX_OTHER_EXTRADATATYPE"); 261c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev return -EINVAL; 262c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev } 263c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 264c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev faceData = ( OMX_FACEDETECTIONTYPE * ) extraData->data; 265c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev if ( NULL != faceData ) { 266c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev if ( sizeof(OMX_FACEDETECTIONTYPE) == faceData->nSize ) { 267c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev CAMHAL_LOGVB("Faces detected %d", 268c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev faceData->ulFaceCount, 269c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev faceData->nSize, 270c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev sizeof(OMX_FACEDETECTIONTYPE), 271c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev faceData->eCameraView, 272c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev faceData->nPortIndex, 273c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev faceData->nVersion); 274c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev } else { 275782a084e5fec691d3985b31c3ab7be1584d879b3Iliyan Malchev CAMHAL_LOGEB("OMX_FACEDETECTIONTYPE size mismatch: expected = %d, received = %d", 276c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev ( unsigned int ) sizeof(OMX_FACEDETECTIONTYPE), 277c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev ( unsigned int ) faceData->nSize); 278c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev return -EINVAL; 279c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev } 280c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev } else { 281c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev CAMHAL_LOGEA("Invalid OMX_FACEDETECTIONTYPE"); 282c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev return -EINVAL; 283c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev } 284c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 285c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev ret = encodeFaceCoordinates(faceData, &faces, previewWidth, previewHeight); 286c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 287c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev if ( NO_ERROR == ret ) { 288c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev result = new CameraFDResult(faces); 289c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev } else { 290c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev result.clear(); 291c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev result = NULL; 292c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev } 293c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 294c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev LOG_FUNCTION_NAME_EXIT; 295c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 296c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev return ret; 297c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev} 298c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 299c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchevstatus_t OMXCameraAdapter::encodeFaceCoordinates(const OMX_FACEDETECTIONTYPE *faceData, 300c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev camera_frame_metadata_t **pFaces, 301c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev size_t previewWidth, 302c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev size_t previewHeight) 303c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev{ 304c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev status_t ret = NO_ERROR; 305c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev camera_face_t *faces; 306c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev camera_frame_metadata_t *faceResult; 307c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev size_t hRange, vRange; 308c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev double tmp; 309c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 310c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev LOG_FUNCTION_NAME; 311c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 312c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev if ( NULL == faceData ) { 313c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev CAMHAL_LOGEA("Invalid OMX_FACEDETECTIONTYPE parameter"); 314c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev return EINVAL; 315c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev } 316c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 317c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev LOG_FUNCTION_NAME 318c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 319c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev hRange = CameraFDResult::RIGHT - CameraFDResult::LEFT; 320c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev vRange = CameraFDResult::BOTTOM - CameraFDResult::TOP; 321c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 322c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev faceResult = ( camera_frame_metadata_t * ) malloc(sizeof(camera_frame_metadata_t)); 323c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev if ( NULL == faceResult ) { 324c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev return -ENOMEM; 325c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev } 326c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 327c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev if ( 0 < faceData->ulFaceCount ) { 328fa28dae0efd774ddd8919e99c0add3e69300ea3aTyler Luu int orient_mult; 329fa28dae0efd774ddd8919e99c0add3e69300ea3aTyler Luu int trans_left, trans_top, trans_right, trans_bot; 330c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 331c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev faces = ( camera_face_t * ) malloc(sizeof(camera_face_t)*faceData->ulFaceCount); 332c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev if ( NULL == faces ) { 333c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev return -ENOMEM; 334c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev } 335c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 336fa28dae0efd774ddd8919e99c0add3e69300ea3aTyler Luu /** 337fa28dae0efd774ddd8919e99c0add3e69300ea3aTyler Luu / * When device is 180 degrees oriented to the sensor, need to translate 338fa28dae0efd774ddd8919e99c0add3e69300ea3aTyler Luu / * the output from Ducati to what Android expects 339fa28dae0efd774ddd8919e99c0add3e69300ea3aTyler Luu / * Ducati always gives face coordinates in this form, irrespective of 340fa28dae0efd774ddd8919e99c0add3e69300ea3aTyler Luu / * rotation, i.e (l,t) always represents the point towards the left eye 341fa28dae0efd774ddd8919e99c0add3e69300ea3aTyler Luu / * and top of hair. 342fa28dae0efd774ddd8919e99c0add3e69300ea3aTyler Luu / * (l, t) 343fa28dae0efd774ddd8919e99c0add3e69300ea3aTyler Luu / * --------------- 344fa28dae0efd774ddd8919e99c0add3e69300ea3aTyler Luu / * - ,,,,,,, - 345fa28dae0efd774ddd8919e99c0add3e69300ea3aTyler Luu / * - | | - 346fa28dae0efd774ddd8919e99c0add3e69300ea3aTyler Luu / * - |<a <a| - 347fa28dae0efd774ddd8919e99c0add3e69300ea3aTyler Luu / * - (| ^ |) - 348fa28dae0efd774ddd8919e99c0add3e69300ea3aTyler Luu / * - | -=- | - 349fa28dae0efd774ddd8919e99c0add3e69300ea3aTyler Luu / * - \_____/ - 350fa28dae0efd774ddd8919e99c0add3e69300ea3aTyler Luu / * --------------- 351fa28dae0efd774ddd8919e99c0add3e69300ea3aTyler Luu / * (r, b) 352fa28dae0efd774ddd8919e99c0add3e69300ea3aTyler Luu / * 353fa28dae0efd774ddd8919e99c0add3e69300ea3aTyler Luu / * However, Android expects the coords to be in respect with what the 354fa28dae0efd774ddd8919e99c0add3e69300ea3aTyler Luu / * sensor is viewing, i.e Android expects sensor to see this with (l,t) 355fa28dae0efd774ddd8919e99c0add3e69300ea3aTyler Luu / * and (r,b) like so: 356fa28dae0efd774ddd8919e99c0add3e69300ea3aTyler Luu / * (l, t) 357fa28dae0efd774ddd8919e99c0add3e69300ea3aTyler Luu / * --------------- 358fa28dae0efd774ddd8919e99c0add3e69300ea3aTyler Luu / * - _____ - 359fa28dae0efd774ddd8919e99c0add3e69300ea3aTyler Luu / * - / \ - 360fa28dae0efd774ddd8919e99c0add3e69300ea3aTyler Luu / * - | -=- | - 361fa28dae0efd774ddd8919e99c0add3e69300ea3aTyler Luu / * - (| ^ |) - 362fa28dae0efd774ddd8919e99c0add3e69300ea3aTyler Luu / * - |a> a>| - 363fa28dae0efd774ddd8919e99c0add3e69300ea3aTyler Luu / * - | | - 364fa28dae0efd774ddd8919e99c0add3e69300ea3aTyler Luu / * - ,,,,,,, - 365fa28dae0efd774ddd8919e99c0add3e69300ea3aTyler Luu / * --------------- 366fa28dae0efd774ddd8919e99c0add3e69300ea3aTyler Luu / * (r, b) 367fa28dae0efd774ddd8919e99c0add3e69300ea3aTyler Luu */ 368c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 3697762bf32b7bd874ce34948eb53a3bfa3906f4aefTyler Luu if (mDeviceOrientation == 180) { 3707762bf32b7bd874ce34948eb53a3bfa3906f4aefTyler Luu orient_mult = -1; 3717762bf32b7bd874ce34948eb53a3bfa3906f4aefTyler Luu trans_left = 2; // right is now left 3727762bf32b7bd874ce34948eb53a3bfa3906f4aefTyler Luu trans_top = 3; // bottom is now top 3737762bf32b7bd874ce34948eb53a3bfa3906f4aefTyler Luu trans_right = 0; // left is now right 3747762bf32b7bd874ce34948eb53a3bfa3906f4aefTyler Luu trans_bot = 1; // top is not bottom 3757762bf32b7bd874ce34948eb53a3bfa3906f4aefTyler Luu } else { 3767762bf32b7bd874ce34948eb53a3bfa3906f4aefTyler Luu orient_mult = 1; 3777762bf32b7bd874ce34948eb53a3bfa3906f4aefTyler Luu trans_left = 0; // left 3787762bf32b7bd874ce34948eb53a3bfa3906f4aefTyler Luu trans_top = 1; // top 3797762bf32b7bd874ce34948eb53a3bfa3906f4aefTyler Luu trans_right = 2; // right 3807762bf32b7bd874ce34948eb53a3bfa3906f4aefTyler Luu trans_bot = 3; // bottom 3817762bf32b7bd874ce34948eb53a3bfa3906f4aefTyler Luu } 3827762bf32b7bd874ce34948eb53a3bfa3906f4aefTyler Luu 383967f1197f015b6d2f3b34e60fa787f7066efb824Sundar Raman int j = 0, i = 0; 384967f1197f015b6d2f3b34e60fa787f7066efb824Sundar Raman for ( ; j < faceData->ulFaceCount ; j++) 385967f1197f015b6d2f3b34e60fa787f7066efb824Sundar Raman { 38652d3388c121469e22bf41d7362640257d8268858Tyler Luu OMX_S32 nLeft = 0; 387e45763a2a361324f1771a6991525e631365ca954Tyler Luu OMX_S32 nTop = 0; 388967f1197f015b6d2f3b34e60fa787f7066efb824Sundar Raman //Face filtering 389967f1197f015b6d2f3b34e60fa787f7066efb824Sundar Raman //For real faces, it is seen that the h/w passes a score >=80 390967f1197f015b6d2f3b34e60fa787f7066efb824Sundar Raman //For false faces, we seem to get even a score of 70 sometimes. 391967f1197f015b6d2f3b34e60fa787f7066efb824Sundar Raman //In order to avoid any issue at application level, we filter 392967f1197f015b6d2f3b34e60fa787f7066efb824Sundar Raman //<=70 score here. 393967f1197f015b6d2f3b34e60fa787f7066efb824Sundar Raman if(faceData->tFacePosition[j].nScore <= FACE_DETECTION_THRESHOLD) 394967f1197f015b6d2f3b34e60fa787f7066efb824Sundar Raman continue; 395967f1197f015b6d2f3b34e60fa787f7066efb824Sundar Raman 39652d3388c121469e22bf41d7362640257d8268858Tyler Luu if (mDeviceOrientation == 180) { 39752d3388c121469e22bf41d7362640257d8268858Tyler Luu // from sensor pov, the left pos is the right corner of the face in pov of frame 3987762bf32b7bd874ce34948eb53a3bfa3906f4aefTyler Luu nLeft = faceData->tFacePosition[j].nLeft + faceData->tFacePosition[j].nWidth; 399e45763a2a361324f1771a6991525e631365ca954Tyler Luu nTop = faceData->tFacePosition[j].nTop + faceData->tFacePosition[j].nHeight; 40052d3388c121469e22bf41d7362640257d8268858Tyler Luu } else { 4017762bf32b7bd874ce34948eb53a3bfa3906f4aefTyler Luu nLeft = faceData->tFacePosition[j].nLeft; 402e45763a2a361324f1771a6991525e631365ca954Tyler Luu nTop = faceData->tFacePosition[j].nTop; 40352d3388c121469e22bf41d7362640257d8268858Tyler Luu } 40452d3388c121469e22bf41d7362640257d8268858Tyler Luu 40552d3388c121469e22bf41d7362640257d8268858Tyler Luu tmp = ( double ) nLeft / ( double ) previewWidth; 406c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev tmp *= hRange; 407c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev tmp -= hRange/2; 408fa28dae0efd774ddd8919e99c0add3e69300ea3aTyler Luu faces[i].rect[trans_left] = tmp; 409c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 410e45763a2a361324f1771a6991525e631365ca954Tyler Luu tmp = ( double ) nTop / ( double )previewHeight; 411c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev tmp *= vRange; 412c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev tmp -= vRange/2; 413fa28dae0efd774ddd8919e99c0add3e69300ea3aTyler Luu faces[i].rect[trans_top] = tmp; 414c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 415967f1197f015b6d2f3b34e60fa787f7066efb824Sundar Raman tmp = ( double ) faceData->tFacePosition[j].nWidth / ( double ) previewWidth; 416c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev tmp *= hRange; 417fa28dae0efd774ddd8919e99c0add3e69300ea3aTyler Luu tmp *= orient_mult; 418fa28dae0efd774ddd8919e99c0add3e69300ea3aTyler Luu faces[i].rect[trans_right] = faces[i].rect[trans_left] + tmp; 419c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 420967f1197f015b6d2f3b34e60fa787f7066efb824Sundar Raman tmp = ( double ) faceData->tFacePosition[j].nHeight / ( double ) previewHeight; 421c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev tmp *= vRange; 422fa28dae0efd774ddd8919e99c0add3e69300ea3aTyler Luu tmp *= orient_mult; 423fa28dae0efd774ddd8919e99c0add3e69300ea3aTyler Luu faces[i].rect[trans_bot] = faces[i].rect[trans_top] + tmp; 424c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 425967f1197f015b6d2f3b34e60fa787f7066efb824Sundar Raman faces[i].score = faceData->tFacePosition[j].nScore; 426c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev faces[i].id = 0; 427c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev faces[i].left_eye[0] = CameraFDResult::INVALID_DATA; 428c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev faces[i].left_eye[1] = CameraFDResult::INVALID_DATA; 429c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev faces[i].right_eye[0] = CameraFDResult::INVALID_DATA; 430c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev faces[i].right_eye[1] = CameraFDResult::INVALID_DATA; 431c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev faces[i].mouth[0] = CameraFDResult::INVALID_DATA; 432c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev faces[i].mouth[1] = CameraFDResult::INVALID_DATA; 433967f1197f015b6d2f3b34e60fa787f7066efb824Sundar Raman i++; 434c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev } 435c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 436967f1197f015b6d2f3b34e60fa787f7066efb824Sundar Raman faceResult->number_of_faces = i; 437c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev faceResult->faces = faces; 438c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 4397762bf32b7bd874ce34948eb53a3bfa3906f4aefTyler Luu for (int i = 0; i < faceResult->number_of_faces; i++) 4407762bf32b7bd874ce34948eb53a3bfa3906f4aefTyler Luu { 4417762bf32b7bd874ce34948eb53a3bfa3906f4aefTyler Luu int centerX = (faces[i].rect[trans_left] + faces[i].rect[trans_right] ) / 2; 4427762bf32b7bd874ce34948eb53a3bfa3906f4aefTyler Luu int centerY = (faces[i].rect[trans_top] + faces[i].rect[trans_bot] ) / 2; 4437762bf32b7bd874ce34948eb53a3bfa3906f4aefTyler Luu 4447762bf32b7bd874ce34948eb53a3bfa3906f4aefTyler Luu int sizeX = (faces[i].rect[trans_right] - faces[i].rect[trans_left] ) ; 4457762bf32b7bd874ce34948eb53a3bfa3906f4aefTyler Luu int sizeY = (faces[i].rect[trans_bot] - faces[i].rect[trans_top] ) ; 4467762bf32b7bd874ce34948eb53a3bfa3906f4aefTyler Luu 4477762bf32b7bd874ce34948eb53a3bfa3906f4aefTyler Luu for (int j = 0; j < faceDetectionNumFacesLastOutput; j++) 4487762bf32b7bd874ce34948eb53a3bfa3906f4aefTyler Luu { 4497762bf32b7bd874ce34948eb53a3bfa3906f4aefTyler Luu int tempCenterX = (faceDetectionLastOutput[j].rect[trans_left] + 4507762bf32b7bd874ce34948eb53a3bfa3906f4aefTyler Luu faceDetectionLastOutput[j].rect[trans_right] ) / 2; 4517762bf32b7bd874ce34948eb53a3bfa3906f4aefTyler Luu int tempCenterY = (faceDetectionLastOutput[j].rect[trans_top] + 4527762bf32b7bd874ce34948eb53a3bfa3906f4aefTyler Luu faceDetectionLastOutput[j].rect[trans_bot] ) / 2; 4537762bf32b7bd874ce34948eb53a3bfa3906f4aefTyler Luu int tempSizeX = (faceDetectionLastOutput[j].rect[trans_right] - 4547762bf32b7bd874ce34948eb53a3bfa3906f4aefTyler Luu faceDetectionLastOutput[j].rect[trans_left] ) ; 4557762bf32b7bd874ce34948eb53a3bfa3906f4aefTyler Luu int tempSizeY = (faceDetectionLastOutput[j].rect[trans_bot] - 4567762bf32b7bd874ce34948eb53a3bfa3906f4aefTyler Luu faceDetectionLastOutput[j].rect[trans_top] ) ; 4577762bf32b7bd874ce34948eb53a3bfa3906f4aefTyler Luu 4587762bf32b7bd874ce34948eb53a3bfa3906f4aefTyler Luu if ( (abs(tempCenterX - centerX) < HorizontalFilterThreshold) && 4597762bf32b7bd874ce34948eb53a3bfa3906f4aefTyler Luu (abs(tempCenterY - centerY) < VerticalFilterThreshold) ) 4607762bf32b7bd874ce34948eb53a3bfa3906f4aefTyler Luu { 4617762bf32b7bd874ce34948eb53a3bfa3906f4aefTyler Luu // Found Face. It did not move too far. 4627762bf32b7bd874ce34948eb53a3bfa3906f4aefTyler Luu // Now check size of rectangle compare to last output 4637762bf32b7bd874ce34948eb53a3bfa3906f4aefTyler Luu if ( (abs (tempSizeX -sizeX) < HorizontalFaceSizeThreshold) && 4647762bf32b7bd874ce34948eb53a3bfa3906f4aefTyler Luu (abs (tempSizeY -sizeY) < VerticalFaceSizeThreshold) ) 4657762bf32b7bd874ce34948eb53a3bfa3906f4aefTyler Luu { 4667762bf32b7bd874ce34948eb53a3bfa3906f4aefTyler Luu // Rectangle is almost same as last time 4677762bf32b7bd874ce34948eb53a3bfa3906f4aefTyler Luu // Output exactly what was done for this face last time. 4687762bf32b7bd874ce34948eb53a3bfa3906f4aefTyler Luu faces[i] = faceDetectionLastOutput[j]; 4697762bf32b7bd874ce34948eb53a3bfa3906f4aefTyler Luu } 4707762bf32b7bd874ce34948eb53a3bfa3906f4aefTyler Luu else 4717762bf32b7bd874ce34948eb53a3bfa3906f4aefTyler Luu { 4727762bf32b7bd874ce34948eb53a3bfa3906f4aefTyler Luu // TODO(XXX): Rectangle size changed but position is same. 4737762bf32b7bd874ce34948eb53a3bfa3906f4aefTyler Luu // Possibly we can apply just positional correctness. 4747762bf32b7bd874ce34948eb53a3bfa3906f4aefTyler Luu } 4757762bf32b7bd874ce34948eb53a3bfa3906f4aefTyler Luu } 4767762bf32b7bd874ce34948eb53a3bfa3906f4aefTyler Luu } 4777762bf32b7bd874ce34948eb53a3bfa3906f4aefTyler Luu } 4787762bf32b7bd874ce34948eb53a3bfa3906f4aefTyler Luu 4797762bf32b7bd874ce34948eb53a3bfa3906f4aefTyler Luu // Save this output for next iteration 4807762bf32b7bd874ce34948eb53a3bfa3906f4aefTyler Luu for (int i = 0; i < faceResult->number_of_faces; i++) 4817762bf32b7bd874ce34948eb53a3bfa3906f4aefTyler Luu { 4827762bf32b7bd874ce34948eb53a3bfa3906f4aefTyler Luu faceDetectionLastOutput[i] = faces[i]; 4837762bf32b7bd874ce34948eb53a3bfa3906f4aefTyler Luu } 4847762bf32b7bd874ce34948eb53a3bfa3906f4aefTyler Luu faceDetectionNumFacesLastOutput = faceResult->number_of_faces; 485c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev } else { 486c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev faceResult->number_of_faces = 0; 487c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev faceResult->faces = NULL; 488c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev } 489c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 490c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev *pFaces = faceResult; 491c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 492c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev LOG_FUNCTION_NAME_EXIT; 493c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 494c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev return ret; 495c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev} 496c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 497c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev}; 498