OMXFD.cpp revision c0fc811b503ef0c0ccd024f77f9ac7d6972f77c8
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
31c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchevnamespace android {
32c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
33c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchevstatus_t OMXCameraAdapter::setParametersFD(const CameraParameters &params,
34c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                                           BaseCameraAdapter::AdapterState state)
35c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev{
36c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    status_t ret = NO_ERROR;
37c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
38c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    LOG_FUNCTION_NAME;
39c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
40c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    LOG_FUNCTION_NAME_EXIT;
41c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
42c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    return ret;
43c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev}
44c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
45c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchevstatus_t OMXCameraAdapter::startFaceDetection()
46c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev{
47c0fc811b503ef0c0ccd024f77f9ac7d6972f77c8Sundar Raman    status_t ret = NO_ERROR;
48c0fc811b503ef0c0ccd024f77f9ac7d6972f77c8Sundar Raman
49c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    Mutex::Autolock lock(mFaceDetectionLock);
50c0fc811b503ef0c0ccd024f77f9ac7d6972f77c8Sundar Raman
51c0fc811b503ef0c0ccd024f77f9ac7d6972f77c8Sundar Raman    ret = setFaceDetection(true, mDeviceOrientation);
52c0fc811b503ef0c0ccd024f77f9ac7d6972f77c8Sundar Raman    if (ret != NO_ERROR) {
53c0fc811b503ef0c0ccd024f77f9ac7d6972f77c8Sundar Raman        goto out;
54c0fc811b503ef0c0ccd024f77f9ac7d6972f77c8Sundar Raman    }
55c0fc811b503ef0c0ccd024f77f9ac7d6972f77c8Sundar Raman
56c0fc811b503ef0c0ccd024f77f9ac7d6972f77c8Sundar Raman    // Overwrite 3A settings with face priority versions
57c0fc811b503ef0c0ccd024f77f9ac7d6972f77c8Sundar Raman    mParameters3A.Exposure = EXPOSURE_FACE_PRIORITY;
58c0fc811b503ef0c0ccd024f77f9ac7d6972f77c8Sundar Raman    mParameters3A.WhiteBallance = WB_FACE_PRIORITY;
59c0fc811b503ef0c0ccd024f77f9ac7d6972f77c8Sundar Raman    mParameters3A.Focus = FOCUS_FACE_PRIORITY;
60c0fc811b503ef0c0ccd024f77f9ac7d6972f77c8Sundar Raman
61c0fc811b503ef0c0ccd024f77f9ac7d6972f77c8Sundar Raman
62c0fc811b503ef0c0ccd024f77f9ac7d6972f77c8Sundar Raman    // Set 3A modes to face priority
63c0fc811b503ef0c0ccd024f77f9ac7d6972f77c8Sundar Raman    ret = setExposureMode(mParameters3A);
64c0fc811b503ef0c0ccd024f77f9ac7d6972f77c8Sundar Raman    if (ret != NO_ERROR) {
65c0fc811b503ef0c0ccd024f77f9ac7d6972f77c8Sundar Raman        goto out;
66c0fc811b503ef0c0ccd024f77f9ac7d6972f77c8Sundar Raman    }
67c0fc811b503ef0c0ccd024f77f9ac7d6972f77c8Sundar Raman
68c0fc811b503ef0c0ccd024f77f9ac7d6972f77c8Sundar Raman
69c0fc811b503ef0c0ccd024f77f9ac7d6972f77c8Sundar Raman    ret = setWBMode(mParameters3A);
70c0fc811b503ef0c0ccd024f77f9ac7d6972f77c8Sundar Raman    if (ret != NO_ERROR) {
71c0fc811b503ef0c0ccd024f77f9ac7d6972f77c8Sundar Raman        goto out;
72c0fc811b503ef0c0ccd024f77f9ac7d6972f77c8Sundar Raman    }
73c0fc811b503ef0c0ccd024f77f9ac7d6972f77c8Sundar Raman
74c0fc811b503ef0c0ccd024f77f9ac7d6972f77c8Sundar Raman out:
75c0fc811b503ef0c0ccd024f77f9ac7d6972f77c8Sundar Raman    return ret;
76c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev}
77c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
78c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchevstatus_t OMXCameraAdapter::stopFaceDetection()
79c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev{
80c0fc811b503ef0c0ccd024f77f9ac7d6972f77c8Sundar Raman    status_t ret = NO_ERROR;
81c0fc811b503ef0c0ccd024f77f9ac7d6972f77c8Sundar Raman    const char *str = NULL;
82c0fc811b503ef0c0ccd024f77f9ac7d6972f77c8Sundar Raman    BaseCameraAdapter::AdapterState state;
83c0fc811b503ef0c0ccd024f77f9ac7d6972f77c8Sundar Raman    BaseCameraAdapter::getState(state);
84c0fc811b503ef0c0ccd024f77f9ac7d6972f77c8Sundar Raman
85c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    Mutex::Autolock lock(mFaceDetectionLock);
86c0fc811b503ef0c0ccd024f77f9ac7d6972f77c8Sundar Raman
87c0fc811b503ef0c0ccd024f77f9ac7d6972f77c8Sundar Raman    ret = setFaceDetection(false, mDeviceOrientation);
88c0fc811b503ef0c0ccd024f77f9ac7d6972f77c8Sundar Raman    if (ret != NO_ERROR) {
89c0fc811b503ef0c0ccd024f77f9ac7d6972f77c8Sundar Raman        goto out;
90c0fc811b503ef0c0ccd024f77f9ac7d6972f77c8Sundar Raman    }
91c0fc811b503ef0c0ccd024f77f9ac7d6972f77c8Sundar Raman
92c0fc811b503ef0c0ccd024f77f9ac7d6972f77c8Sundar Raman    // Reset 3A settings
93c0fc811b503ef0c0ccd024f77f9ac7d6972f77c8Sundar Raman    ret = setParameters3A(mParams, state);
94c0fc811b503ef0c0ccd024f77f9ac7d6972f77c8Sundar Raman    if (ret != NO_ERROR) {
95c0fc811b503ef0c0ccd024f77f9ac7d6972f77c8Sundar Raman        goto out;
96c0fc811b503ef0c0ccd024f77f9ac7d6972f77c8Sundar Raman    }
97c0fc811b503ef0c0ccd024f77f9ac7d6972f77c8Sundar Raman
98c0fc811b503ef0c0ccd024f77f9ac7d6972f77c8Sundar Raman    if (mPending3Asettings) {
99c0fc811b503ef0c0ccd024f77f9ac7d6972f77c8Sundar Raman        apply3Asettings(mParameters3A);
100c0fc811b503ef0c0ccd024f77f9ac7d6972f77c8Sundar Raman    }
101c0fc811b503ef0c0ccd024f77f9ac7d6972f77c8Sundar Raman
102c0fc811b503ef0c0ccd024f77f9ac7d6972f77c8Sundar Raman out:
103c0fc811b503ef0c0ccd024f77f9ac7d6972f77c8Sundar Raman    return ret;
104c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev}
105c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
106aa6e62e279cb54ae76c55ba9f8d02da230ce34e7Tyler Luuvoid OMXCameraAdapter::pauseFaceDetection(bool pause)
107aa6e62e279cb54ae76c55ba9f8d02da230ce34e7Tyler Luu{
108aa6e62e279cb54ae76c55ba9f8d02da230ce34e7Tyler Luu    Mutex::Autolock lock(mFaceDetectionLock);
109aa6e62e279cb54ae76c55ba9f8d02da230ce34e7Tyler Luu    // pausing will only take affect if fd is already running
110aa6e62e279cb54ae76c55ba9f8d02da230ce34e7Tyler Luu    if (mFaceDetectionRunning) {
111aa6e62e279cb54ae76c55ba9f8d02da230ce34e7Tyler Luu        mFaceDetectionPaused = pause;
112aa6e62e279cb54ae76c55ba9f8d02da230ce34e7Tyler Luu    }
113aa6e62e279cb54ae76c55ba9f8d02da230ce34e7Tyler Luu}
114aa6e62e279cb54ae76c55ba9f8d02da230ce34e7Tyler Luu
115c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchevstatus_t OMXCameraAdapter::setFaceDetection(bool enable, OMX_U32 orientation)
116c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev{
117c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    status_t ret = NO_ERROR;
118c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    OMX_ERRORTYPE eError = OMX_ErrorNone;
119c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    OMX_CONFIG_EXTRADATATYPE extraDataControl;
120c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    OMX_CONFIG_OBJDETECTIONTYPE objDetection;
121c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
122c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    LOG_FUNCTION_NAME;
123c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
124c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    if ( OMX_StateInvalid == mComponentState )
125c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        {
126c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        CAMHAL_LOGEA("OMX component is in invalid state");
127c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        ret = -EINVAL;
128c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        }
129c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
130c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    if ( NO_ERROR == ret )
131c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        {
132c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        if ( orientation < 0 || orientation > 270 ) {
133c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            orientation = 0;
134c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        }
135c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
136c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        OMX_INIT_STRUCT_PTR (&objDetection, OMX_CONFIG_OBJDETECTIONTYPE);
137c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        objDetection.nPortIndex = mCameraAdapterParameters.mPrevPortIndex;
138c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        objDetection.nDeviceOrientation = orientation;
139c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        if  ( enable )
140c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            {
141c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            objDetection.bEnable = OMX_TRUE;
142c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            }
143c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        else
144c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            {
145c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            objDetection.bEnable = OMX_FALSE;
146c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            }
147c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
148c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        eError =  OMX_SetConfig(mCameraAdapterParameters.mHandleComp,
149c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                                ( OMX_INDEXTYPE ) OMX_IndexConfigImageFaceDetection,
150c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                                &objDetection);
151c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        if ( OMX_ErrorNone != eError )
152c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            {
153c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            CAMHAL_LOGEB("Error while configuring face detection 0x%x", eError);
154c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            ret = -1;
155c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            }
156c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        else
157c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            {
158c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            CAMHAL_LOGDA("Face detection configured successfully");
159c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            }
160c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        }
161c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
162c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    if ( NO_ERROR == ret )
163c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        {
164c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        OMX_INIT_STRUCT_PTR (&extraDataControl, OMX_CONFIG_EXTRADATATYPE);
165c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        extraDataControl.nPortIndex = mCameraAdapterParameters.mPrevPortIndex;
166c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        extraDataControl.eExtraDataType = OMX_FaceDetection;
167c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        extraDataControl.eCameraView = OMX_2D;
168c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        if  ( enable )
169c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            {
170c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            extraDataControl.bEnable = OMX_TRUE;
171c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            }
172c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        else
173c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            {
174c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            extraDataControl.bEnable = OMX_FALSE;
175c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            }
176c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
177c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        eError =  OMX_SetConfig(mCameraAdapterParameters.mHandleComp,
178c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                                ( OMX_INDEXTYPE ) OMX_IndexConfigOtherExtraDataControl,
179c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                                &extraDataControl);
180c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        if ( OMX_ErrorNone != eError )
181c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            {
182c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            CAMHAL_LOGEB("Error while configuring face detection extra data 0x%x",
183c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                         eError);
184c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            ret = -1;
185c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            }
186c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        else
187c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            {
188c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            CAMHAL_LOGDA("Face detection extra data configured successfully");
189c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            }
190c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        }
191c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
192c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    if ( NO_ERROR == ret )
193c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        {
194c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        mFaceDetectionRunning = enable;
195aa6e62e279cb54ae76c55ba9f8d02da230ce34e7Tyler Luu        mFaceDetectionPaused = !enable;
196c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        }
197c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
198c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    LOG_FUNCTION_NAME_EXIT;
199c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
200c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    return ret;
201c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev}
202c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
203c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchevstatus_t OMXCameraAdapter::detectFaces(OMX_BUFFERHEADERTYPE* pBuffHeader,
204c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                                       sp<CameraFDResult> &result,
205c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                                       size_t previewWidth,
206c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                                       size_t previewHeight)
207c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev{
208c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    status_t ret = NO_ERROR;
209c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    OMX_ERRORTYPE eError = OMX_ErrorNone;
210c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    OMX_TI_FACERESULT *faceResult;
211c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    OMX_OTHER_EXTRADATATYPE *extraData;
212c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    OMX_FACEDETECTIONTYPE *faceData;
213c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    OMX_TI_PLATFORMPRIVATE *platformPrivate;
214c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    camera_frame_metadata_t *faces;
215c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
216c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    LOG_FUNCTION_NAME;
217c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
218c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    if ( OMX_StateExecuting != mComponentState ) {
219c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        CAMHAL_LOGEA("OMX component is not in executing state");
220c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        return NO_INIT;
221c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    }
222c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
223c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    if ( NULL == pBuffHeader ) {
224c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        CAMHAL_LOGEA("Invalid Buffer header");
225c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        return-EINVAL;
226c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    }
227c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
228c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    platformPrivate = (OMX_TI_PLATFORMPRIVATE *) (pBuffHeader->pPlatformPrivate);
229c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    if ( NULL != platformPrivate ) {
230c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        if ( sizeof(OMX_TI_PLATFORMPRIVATE) == platformPrivate->nSize ) {
231c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            CAMHAL_LOGVB("Size = %d, sizeof = %d, pAuxBuf = 0x%x, pAuxBufSize= %d, pMetaDataBufer = 0x%x, nMetaDataSize = %d",
232c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                         platformPrivate->nSize,
233c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                         sizeof(OMX_TI_PLATFORMPRIVATE),
234c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                         platformPrivate->pAuxBuf1,
235c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                         platformPrivate->pAuxBufSize1,
236c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                         platformPrivate->pMetaDataBuffer,
237c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                         platformPrivate->nMetaDataSize);
238c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        } else {
239c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            CAMHAL_LOGEB("OMX_TI_PLATFORMPRIVATE size mismatch: expected = %d, received = %d",
240c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                         ( unsigned int ) sizeof(OMX_TI_PLATFORMPRIVATE),
241c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                         ( unsigned int ) platformPrivate->nSize);
242c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            ret = -EINVAL;
243c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        }
244c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    }  else {
245c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        CAMHAL_LOGEA("Invalid OMX_TI_PLATFORMPRIVATE");
246c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        return-EINVAL;
247c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    }
248c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
249c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
250c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    if ( 0 >= platformPrivate->nMetaDataSize ) {
251c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        CAMHAL_LOGEB("OMX_TI_PLATFORMPRIVATE nMetaDataSize is size is %d",
252c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                     ( unsigned int ) platformPrivate->nMetaDataSize);
253c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        return -EINVAL;
254c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    }
255c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
256c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    extraData = (OMX_OTHER_EXTRADATATYPE *) (platformPrivate->pMetaDataBuffer);
257c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    if ( NULL != extraData ) {
258c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        CAMHAL_LOGVB("Size = %d, sizeof = %d, eType = 0x%x, nDataSize= %d, nPortIndex = 0x%x, nVersion = 0x%x",
259c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                     extraData->nSize,
260c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                     sizeof(OMX_OTHER_EXTRADATATYPE),
261c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                     extraData->eType,
262c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                     extraData->nDataSize,
263c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                     extraData->nPortIndex,
264c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                     extraData->nVersion);
265c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    } else {
266c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        CAMHAL_LOGEA("Invalid OMX_OTHER_EXTRADATATYPE");
267c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        return -EINVAL;
268c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    }
269c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
270c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    faceData = ( OMX_FACEDETECTIONTYPE * ) extraData->data;
271c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    if ( NULL != faceData ) {
272c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        if ( sizeof(OMX_FACEDETECTIONTYPE) == faceData->nSize ) {
273c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            CAMHAL_LOGVB("Faces detected %d",
274c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                         faceData->ulFaceCount,
275c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                         faceData->nSize,
276c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                         sizeof(OMX_FACEDETECTIONTYPE),
277c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                         faceData->eCameraView,
278c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                         faceData->nPortIndex,
279c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                         faceData->nVersion);
280c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        } else {
281782a084e5fec691d3985b31c3ab7be1584d879b3Iliyan Malchev            CAMHAL_LOGEB("OMX_FACEDETECTIONTYPE size mismatch: expected = %d, received = %d",
282c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                         ( unsigned int ) sizeof(OMX_FACEDETECTIONTYPE),
283c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                         ( unsigned int ) faceData->nSize);
284c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            return -EINVAL;
285c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        }
286c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    } else {
287c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        CAMHAL_LOGEA("Invalid OMX_FACEDETECTIONTYPE");
288c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        return -EINVAL;
289c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    }
290c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
291c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    ret = encodeFaceCoordinates(faceData, &faces, previewWidth, previewHeight);
292c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
293c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    if ( NO_ERROR == ret ) {
294c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        result = new CameraFDResult(faces);
295c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    } else {
296c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        result.clear();
297c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        result = NULL;
298c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    }
299c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
300c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    LOG_FUNCTION_NAME_EXIT;
301c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
302c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    return ret;
303c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev}
304c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
305c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchevstatus_t OMXCameraAdapter::encodeFaceCoordinates(const OMX_FACEDETECTIONTYPE *faceData,
306c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                                                 camera_frame_metadata_t **pFaces,
307c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                                                 size_t previewWidth,
308c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                                                 size_t previewHeight)
309c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev{
310c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    status_t ret = NO_ERROR;
311c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    camera_face_t *faces;
312c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    camera_frame_metadata_t *faceResult;
313c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    size_t hRange, vRange;
314c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    double tmp;
315c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
316c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    LOG_FUNCTION_NAME;
317c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
318c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    if ( NULL == faceData ) {
319c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        CAMHAL_LOGEA("Invalid OMX_FACEDETECTIONTYPE parameter");
320c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        return EINVAL;
321c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    }
322c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
323c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    LOG_FUNCTION_NAME
324c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
325c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    hRange = CameraFDResult::RIGHT - CameraFDResult::LEFT;
326c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    vRange = CameraFDResult::BOTTOM - CameraFDResult::TOP;
327c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
328c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    faceResult = ( camera_frame_metadata_t * ) malloc(sizeof(camera_frame_metadata_t));
329c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    if ( NULL == faceResult ) {
330c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        return -ENOMEM;
331c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    }
332c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
333c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    if ( 0 < faceData->ulFaceCount ) {
334fa28dae0efd774ddd8919e99c0add3e69300ea3aTyler Luu        int orient_mult;
335fa28dae0efd774ddd8919e99c0add3e69300ea3aTyler Luu        int trans_left, trans_top, trans_right, trans_bot;
336c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
337c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        faces = ( camera_face_t * ) malloc(sizeof(camera_face_t)*faceData->ulFaceCount);
338c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        if ( NULL == faces ) {
339c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            return -ENOMEM;
340c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        }
341c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
342fa28dae0efd774ddd8919e99c0add3e69300ea3aTyler Luu        /**
343fa28dae0efd774ddd8919e99c0add3e69300ea3aTyler Luu        / * When device is 180 degrees oriented to the sensor, need to translate
344fa28dae0efd774ddd8919e99c0add3e69300ea3aTyler Luu        / * the output from Ducati to what Android expects
345fa28dae0efd774ddd8919e99c0add3e69300ea3aTyler Luu        / * Ducati always gives face coordinates in this form, irrespective of
346fa28dae0efd774ddd8919e99c0add3e69300ea3aTyler Luu        / * rotation, i.e (l,t) always represents the point towards the left eye
347fa28dae0efd774ddd8919e99c0add3e69300ea3aTyler Luu        / * and top of hair.
348fa28dae0efd774ddd8919e99c0add3e69300ea3aTyler Luu        / * (l, t)
349fa28dae0efd774ddd8919e99c0add3e69300ea3aTyler Luu        / *   ---------------
350fa28dae0efd774ddd8919e99c0add3e69300ea3aTyler Luu        / *   -   ,,,,,,,   -
351fa28dae0efd774ddd8919e99c0add3e69300ea3aTyler Luu        / *   -  |       |  -
352fa28dae0efd774ddd8919e99c0add3e69300ea3aTyler Luu        / *   -  |<a   <a|  -
353fa28dae0efd774ddd8919e99c0add3e69300ea3aTyler Luu        / *   - (|   ^   |) -
354fa28dae0efd774ddd8919e99c0add3e69300ea3aTyler Luu        / *   -  |  -=-  |  -
355fa28dae0efd774ddd8919e99c0add3e69300ea3aTyler Luu        / *   -   \_____/   -
356fa28dae0efd774ddd8919e99c0add3e69300ea3aTyler Luu        / *   ---------------
357fa28dae0efd774ddd8919e99c0add3e69300ea3aTyler Luu        / *               (r, b)
358fa28dae0efd774ddd8919e99c0add3e69300ea3aTyler Luu        / *
359fa28dae0efd774ddd8919e99c0add3e69300ea3aTyler Luu        / * However, Android expects the coords to be in respect with what the
360fa28dae0efd774ddd8919e99c0add3e69300ea3aTyler Luu        / * sensor is viewing, i.e Android expects sensor to see this with (l,t)
361fa28dae0efd774ddd8919e99c0add3e69300ea3aTyler Luu        / * and (r,b) like so:
362fa28dae0efd774ddd8919e99c0add3e69300ea3aTyler Luu        / * (l, t)
363fa28dae0efd774ddd8919e99c0add3e69300ea3aTyler Luu        / *   ---------------
364fa28dae0efd774ddd8919e99c0add3e69300ea3aTyler Luu        / *   -    _____    -
365fa28dae0efd774ddd8919e99c0add3e69300ea3aTyler Luu        / *   -   /     \   -
366fa28dae0efd774ddd8919e99c0add3e69300ea3aTyler Luu        / *   -  |  -=-  |  -
367fa28dae0efd774ddd8919e99c0add3e69300ea3aTyler Luu        / *   - (|   ^   |) -
368fa28dae0efd774ddd8919e99c0add3e69300ea3aTyler Luu        / *   -  |a>   a>|  -
369fa28dae0efd774ddd8919e99c0add3e69300ea3aTyler Luu        / *   -  |       |  -
370fa28dae0efd774ddd8919e99c0add3e69300ea3aTyler Luu        / *   -   ,,,,,,,   -
371fa28dae0efd774ddd8919e99c0add3e69300ea3aTyler Luu        / *   ---------------
372fa28dae0efd774ddd8919e99c0add3e69300ea3aTyler Luu        / *               (r, b)
373fa28dae0efd774ddd8919e99c0add3e69300ea3aTyler Luu          */
374fa28dae0efd774ddd8919e99c0add3e69300ea3aTyler Luu        if (mDeviceOrientation == 180) {
375fa28dae0efd774ddd8919e99c0add3e69300ea3aTyler Luu            orient_mult = -1;
376fa28dae0efd774ddd8919e99c0add3e69300ea3aTyler Luu            trans_left = 2; // right is now left
377fa28dae0efd774ddd8919e99c0add3e69300ea3aTyler Luu            trans_top = 3; // bottom is now top
378fa28dae0efd774ddd8919e99c0add3e69300ea3aTyler Luu            trans_right = 0; // left is now right
379fa28dae0efd774ddd8919e99c0add3e69300ea3aTyler Luu            trans_bot = 1; // top is not bottom
380fa28dae0efd774ddd8919e99c0add3e69300ea3aTyler Luu        } else {
381fa28dae0efd774ddd8919e99c0add3e69300ea3aTyler Luu            orient_mult = 1;
382fa28dae0efd774ddd8919e99c0add3e69300ea3aTyler Luu            trans_left = 0; // left
383fa28dae0efd774ddd8919e99c0add3e69300ea3aTyler Luu            trans_top = 1; // top
384fa28dae0efd774ddd8919e99c0add3e69300ea3aTyler Luu            trans_right = 2; // right
385fa28dae0efd774ddd8919e99c0add3e69300ea3aTyler Luu            trans_bot = 3; // bottom
386fa28dae0efd774ddd8919e99c0add3e69300ea3aTyler Luu
387fa28dae0efd774ddd8919e99c0add3e69300ea3aTyler Luu        }
388c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        for ( int i = 0  ; i < faceData->ulFaceCount ; i++)
389c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            {
390c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
391c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            tmp = ( double ) faceData->tFacePosition[i].nLeft / ( double ) previewWidth;
392c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            tmp *= hRange;
393c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            tmp -= hRange/2;
394fa28dae0efd774ddd8919e99c0add3e69300ea3aTyler Luu            faces[i].rect[trans_left] = tmp;
395c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
396c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            tmp = ( double ) faceData->tFacePosition[i].nTop / ( double )previewHeight;
397c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            tmp *= vRange;
398c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            tmp -= vRange/2;
399fa28dae0efd774ddd8919e99c0add3e69300ea3aTyler Luu            faces[i].rect[trans_top] = tmp;
400c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
401c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            tmp = ( double ) faceData->tFacePosition[i].nWidth / ( double ) previewWidth;
402c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            tmp *= hRange;
403fa28dae0efd774ddd8919e99c0add3e69300ea3aTyler Luu            tmp *= orient_mult;
404fa28dae0efd774ddd8919e99c0add3e69300ea3aTyler Luu            faces[i].rect[trans_right] = faces[i].rect[trans_left] + tmp;
405c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
406c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            tmp = ( double ) faceData->tFacePosition[i].nHeight / ( double ) previewHeight;
407c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            tmp *= vRange;
408fa28dae0efd774ddd8919e99c0add3e69300ea3aTyler Luu            tmp *= orient_mult;
409fa28dae0efd774ddd8919e99c0add3e69300ea3aTyler Luu            faces[i].rect[trans_bot] = faces[i].rect[trans_top] + tmp;
410c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
411c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            faces[i].score = faceData->tFacePosition[i].nScore;
412c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            faces[i].id = 0;
413c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            faces[i].left_eye[0] = CameraFDResult::INVALID_DATA;
414c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            faces[i].left_eye[1] = CameraFDResult::INVALID_DATA;
415c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            faces[i].right_eye[0] = CameraFDResult::INVALID_DATA;
416c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            faces[i].right_eye[1] = CameraFDResult::INVALID_DATA;
417c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            faces[i].mouth[0] = CameraFDResult::INVALID_DATA;
418c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            faces[i].mouth[1] = CameraFDResult::INVALID_DATA;
419c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            }
420c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
421c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        faceResult->number_of_faces = faceData->ulFaceCount;
422c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        faceResult->faces = faces;
423c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
424c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    } else {
425c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        faceResult->number_of_faces = 0;
426c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        faceResult->faces = NULL;
427c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    }
428c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
429c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    *pFaces = faceResult;
430c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
431c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    LOG_FUNCTION_NAME_EXIT;
432c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
433c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    return ret;
434c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev}
435c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
436c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev};
437