summaryrefslogtreecommitdiffstats
path: root/camera/OMXCameraAdapter/OMXFD.cpp
diff options
context:
space:
mode:
authorIliyan Malchev <malchev@google.com>2011-08-08 11:24:41 -0700
committerIliyan Malchev <malchev@google.com>2011-08-08 11:46:17 -0700
commitc322989ae6ff6769490828de1b5eda12b749cce9 (patch)
treecfd1494d18791389b1a743242085f128e8a030fd /camera/OMXCameraAdapter/OMXFD.cpp
parent8558b0909d3f42288f488e6fd1341877c639a594 (diff)
downloadhardware_ti_omap4xxx-c322989ae6ff6769490828de1b5eda12b749cce9.tar.gz
hardware_ti_omap4xxx-c322989ae6ff6769490828de1b5eda12b749cce9.tar.bz2
hardware_ti_omap4xxx-c322989ae6ff6769490828de1b5eda12b749cce9.zip
initial commit
Change-Id: I8f7a7eeece0e516efa486b77e9d97805c0e65d3e Signed-off-by: Iliyan Malchev <malchev@google.com>
Diffstat (limited to 'camera/OMXCameraAdapter/OMXFD.cpp')
-rw-r--r--camera/OMXCameraAdapter/OMXFD.cpp327
1 files changed, 327 insertions, 0 deletions
diff --git a/camera/OMXCameraAdapter/OMXFD.cpp b/camera/OMXCameraAdapter/OMXFD.cpp
new file mode 100644
index 0000000..c1617d7
--- /dev/null
+++ b/camera/OMXCameraAdapter/OMXFD.cpp
@@ -0,0 +1,327 @@
+/*
+ * 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.
+*
+*/
+
+#undef LOG_TAG
+
+#define LOG_TAG "CameraHAL"
+
+#include "CameraHal.h"
+#include "OMXCameraAdapter.h"
+
+namespace android {
+
+status_t OMXCameraAdapter::setParametersFD(const CameraParameters &params,
+ BaseCameraAdapter::AdapterState state)
+{
+ status_t ret = NO_ERROR;
+
+ LOG_FUNCTION_NAME;
+
+ LOG_FUNCTION_NAME_EXIT;
+
+ return ret;
+}
+
+status_t OMXCameraAdapter::startFaceDetection()
+{
+ Mutex::Autolock lock(mFaceDetectionLock);
+ return setFaceDetection(true, mDeviceOrientation);
+}
+
+status_t OMXCameraAdapter::stopFaceDetection()
+{
+ Mutex::Autolock lock(mFaceDetectionLock);
+ return setFaceDetection(false, mDeviceOrientation);
+}
+
+status_t OMXCameraAdapter::setFaceDetection(bool enable, OMX_U32 orientation)
+{
+ status_t ret = NO_ERROR;
+ OMX_ERRORTYPE eError = OMX_ErrorNone;
+ OMX_CONFIG_EXTRADATATYPE extraDataControl;
+ 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 < 0 || 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 )
+ {
+ OMX_INIT_STRUCT_PTR (&extraDataControl, OMX_CONFIG_EXTRADATATYPE);
+ extraDataControl.nPortIndex = mCameraAdapterParameters.mPrevPortIndex;
+ extraDataControl.eExtraDataType = OMX_FaceDetection;
+ extraDataControl.eCameraView = OMX_2D;
+ if ( enable )
+ {
+ extraDataControl.bEnable = OMX_TRUE;
+ }
+ else
+ {
+ extraDataControl.bEnable = OMX_FALSE;
+ }
+
+ eError = OMX_SetConfig(mCameraAdapterParameters.mHandleComp,
+ ( OMX_INDEXTYPE ) OMX_IndexConfigOtherExtraDataControl,
+ &extraDataControl);
+ if ( OMX_ErrorNone != eError )
+ {
+ CAMHAL_LOGEB("Error while configuring face detection extra data 0x%x",
+ eError);
+ ret = -1;
+ }
+ else
+ {
+ CAMHAL_LOGDA("Face detection extra data configured successfully");
+ }
+ }
+
+ if ( NO_ERROR == ret )
+ {
+ mFaceDetectionRunning = enable;
+ }
+
+ LOG_FUNCTION_NAME_EXIT;
+
+ return ret;
+}
+
+status_t OMXCameraAdapter::detectFaces(OMX_BUFFERHEADERTYPE* pBuffHeader,
+ sp<CameraFDResult> &result,
+ size_t previewWidth,
+ size_t previewHeight)
+{
+ status_t ret = NO_ERROR;
+ OMX_ERRORTYPE eError = OMX_ErrorNone;
+ OMX_TI_FACERESULT *faceResult;
+ OMX_OTHER_EXTRADATATYPE *extraData;
+ OMX_FACEDETECTIONTYPE *faceData;
+ OMX_TI_PLATFORMPRIVATE *platformPrivate;
+ camera_frame_metadata_t *faces;
+
+ 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;
+ }
+
+ platformPrivate = (OMX_TI_PLATFORMPRIVATE *) (pBuffHeader->pPlatformPrivate);
+ if ( NULL != platformPrivate ) {
+ if ( sizeof(OMX_TI_PLATFORMPRIVATE) == platformPrivate->nSize ) {
+ CAMHAL_LOGVB("Size = %d, sizeof = %d, pAuxBuf = 0x%x, pAuxBufSize= %d, pMetaDataBufer = 0x%x, nMetaDataSize = %d",
+ platformPrivate->nSize,
+ sizeof(OMX_TI_PLATFORMPRIVATE),
+ platformPrivate->pAuxBuf1,
+ platformPrivate->pAuxBufSize1,
+ platformPrivate->pMetaDataBuffer,
+ platformPrivate->nMetaDataSize);
+ } else {
+ CAMHAL_LOGEB("OMX_TI_PLATFORMPRIVATE size mismatch: expected = %d, received = %d",
+ ( unsigned int ) sizeof(OMX_TI_PLATFORMPRIVATE),
+ ( unsigned int ) platformPrivate->nSize);
+ ret = -EINVAL;
+ }
+ } else {
+ CAMHAL_LOGEA("Invalid OMX_TI_PLATFORMPRIVATE");
+ return-EINVAL;
+ }
+
+
+ if ( 0 >= platformPrivate->nMetaDataSize ) {
+ CAMHAL_LOGEB("OMX_TI_PLATFORMPRIVATE nMetaDataSize is size is %d",
+ ( unsigned int ) platformPrivate->nMetaDataSize);
+ return -EINVAL;
+ }
+
+ extraData = (OMX_OTHER_EXTRADATATYPE *) (platformPrivate->pMetaDataBuffer);
+ if ( NULL != extraData ) {
+ CAMHAL_LOGVB("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_LOGEA("Invalid OMX_OTHER_EXTRADATATYPE");
+ return -EINVAL;
+ }
+
+ faceData = ( OMX_FACEDETECTIONTYPE * ) extraData->data;
+ if ( NULL != faceData ) {
+ if ( sizeof(OMX_FACEDETECTIONTYPE) == faceData->nSize ) {
+ CAMHAL_LOGVB("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;
+ }
+
+ ret = encodeFaceCoordinates(faceData, &faces, previewWidth, previewHeight);
+
+ if ( NO_ERROR == ret ) {
+ result = new CameraFDResult(faces);
+ } else {
+ result.clear();
+ result = NULL;
+ }
+
+ LOG_FUNCTION_NAME_EXIT;
+
+ return ret;
+}
+
+status_t OMXCameraAdapter::encodeFaceCoordinates(const OMX_FACEDETECTIONTYPE *faceData,
+ camera_frame_metadata_t **pFaces,
+ size_t previewWidth,
+ size_t previewHeight)
+{
+ status_t ret = NO_ERROR;
+ camera_face_t *faces;
+ camera_frame_metadata_t *faceResult;
+ size_t hRange, vRange;
+ double tmp;
+
+ LOG_FUNCTION_NAME;
+
+ if ( NULL == faceData ) {
+ CAMHAL_LOGEA("Invalid OMX_FACEDETECTIONTYPE parameter");
+ return EINVAL;
+ }
+
+ LOG_FUNCTION_NAME
+
+ hRange = CameraFDResult::RIGHT - CameraFDResult::LEFT;
+ vRange = CameraFDResult::BOTTOM - CameraFDResult::TOP;
+
+ faceResult = ( camera_frame_metadata_t * ) malloc(sizeof(camera_frame_metadata_t));
+ if ( NULL == faceResult ) {
+ return -ENOMEM;
+ }
+
+ if ( 0 < faceData->ulFaceCount ) {
+
+ faces = ( camera_face_t * ) malloc(sizeof(camera_face_t)*faceData->ulFaceCount);
+ if ( NULL == faces ) {
+ return -ENOMEM;
+ }
+
+ for ( int i = 0 ; i < faceData->ulFaceCount ; i++)
+ {
+
+ tmp = ( double ) faceData->tFacePosition[i].nLeft / ( double ) previewWidth;
+ tmp *= hRange;
+ tmp -= hRange/2;
+ faces[i].rect[0] = tmp;
+
+ tmp = ( double ) faceData->tFacePosition[i].nTop / ( double )previewHeight;
+ tmp *= vRange;
+ tmp -= vRange/2;
+ faces[i].rect[1] = tmp;
+
+ tmp = ( double ) faceData->tFacePosition[i].nWidth / ( double ) previewWidth;
+ tmp *= hRange;
+ faces[i].rect[2] = faces[i].rect[0] + tmp;
+
+ tmp = ( double ) faceData->tFacePosition[i].nHeight / ( double ) previewHeight;
+ tmp *= vRange;
+ faces[i].rect[3] = faces[i].rect[1] + tmp;
+
+ faces[i].score = faceData->tFacePosition[i].nScore;
+ faces[i].id = 0;
+ faces[i].left_eye[0] = CameraFDResult::INVALID_DATA;
+ faces[i].left_eye[1] = CameraFDResult::INVALID_DATA;
+ faces[i].right_eye[0] = CameraFDResult::INVALID_DATA;
+ faces[i].right_eye[1] = CameraFDResult::INVALID_DATA;
+ faces[i].mouth[0] = CameraFDResult::INVALID_DATA;
+ faces[i].mouth[1] = CameraFDResult::INVALID_DATA;
+ }
+
+ faceResult->number_of_faces = faceData->ulFaceCount;
+ faceResult->faces = faces;
+
+ } else {
+ faceResult->number_of_faces = 0;
+ faceResult->faces = NULL;
+ }
+
+ *pFaces = faceResult;
+
+ LOG_FUNCTION_NAME_EXIT;
+
+ return ret;
+}
+
+};