FrameProcessor.cpp revision a9f8d040146533a9c214473fd79cbd9dff44428d
1/* 2 * Copyright (C) 2012 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#define LOG_TAG "Camera2Client::FrameProcessor" 18#define ATRACE_TAG ATRACE_TAG_CAMERA 19//#define LOG_NDEBUG 0 20 21#include <utils/Log.h> 22#include <utils/Trace.h> 23 24#include "FrameProcessor.h" 25#include "../Camera2Device.h" 26#include "../Camera2Client.h" 27 28namespace android { 29namespace camera2 { 30 31FrameProcessor::FrameProcessor(wp<Camera2Client> client): 32 Thread(false), mClient(client) { 33} 34 35FrameProcessor::~FrameProcessor() { 36 ALOGV("%s: Exit", __FUNCTION__); 37} 38 39status_t FrameProcessor::registerListener(int32_t id, 40 wp<FilteredListener> listener) { 41 Mutex::Autolock l(mInputMutex); 42 ALOGV("%s: Registering listener for frame id %d", 43 __FUNCTION__, id); 44 return mListeners.replaceValueFor(id, listener); 45} 46 47status_t FrameProcessor::removeListener(int32_t id) { 48 Mutex::Autolock l(mInputMutex); 49 return mListeners.removeItem(id); 50} 51 52void FrameProcessor::dump(int fd, const Vector<String16>& args) { 53 String8 result(" Latest received frame:\n"); 54 write(fd, result.string(), result.size()); 55 mLastFrame.dump(fd, 2, 6); 56} 57 58bool FrameProcessor::threadLoop() { 59 status_t res; 60 61 sp<Camera2Device> device; 62 { 63 sp<Camera2Client> client = mClient.promote(); 64 if (client == 0) return false; 65 device = client->getCameraDevice(); 66 if (device == 0) return false; 67 } 68 69 res = device->waitForNextFrame(kWaitDuration); 70 if (res == OK) { 71 sp<Camera2Client> client = mClient.promote(); 72 if (client == 0) return false; 73 processNewFrames(client); 74 } else if (res != TIMED_OUT) { 75 ALOGE("Camera2Client::FrameProcessor: Error waiting for new " 76 "frames: %s (%d)", strerror(-res), res); 77 } 78 79 return true; 80} 81 82void FrameProcessor::processNewFrames(sp<Camera2Client> &client) { 83 status_t res; 84 ATRACE_CALL(); 85 CameraMetadata frame; 86 while ( (res = client->getCameraDevice()->getNextFrame(&frame)) == OK) { 87 camera_metadata_entry_t entry; 88 89 entry = frame.find(ANDROID_REQUEST_FRAME_COUNT); 90 if (entry.count == 0) { 91 ALOGE("%s: Camera %d: Error reading frame number", 92 __FUNCTION__, client->getCameraId()); 93 break; 94 } 95 96 res = processFaceDetect(frame, client); 97 if (res != OK) break; 98 99 // Must be last - listener can take ownership of frame 100 res = processListener(frame, client); 101 if (res != OK) break; 102 103 if (!frame.isEmpty()) { 104 mLastFrame.acquire(frame); 105 } 106 } 107 if (res != NOT_ENOUGH_DATA) { 108 ALOGE("%s: Camera %d: Error getting next frame: %s (%d)", 109 __FUNCTION__, client->getCameraId(), strerror(-res), res); 110 return; 111 } 112 113 return; 114} 115 116status_t FrameProcessor::processListener(CameraMetadata &frame, 117 sp<Camera2Client> &client) { 118 status_t res; 119 ATRACE_CALL(); 120 camera_metadata_entry_t entry; 121 122 entry = frame.find(ANDROID_REQUEST_ID); 123 if (entry.count == 0) { 124 ALOGE("%s: Camera %d: Error reading frame id", 125 __FUNCTION__, client->getCameraId()); 126 return BAD_VALUE; 127 } 128 int32_t frameId = entry.data.i32[0]; 129 ALOGV("%s: Got frame with ID %d", __FUNCTION__, frameId); 130 131 sp<FilteredListener> listener; 132 { 133 Mutex::Autolock l(mInputMutex); 134 ssize_t listenerIndex = mListeners.indexOfKey(frameId); 135 if (listenerIndex != NAME_NOT_FOUND) { 136 listener = mListeners[listenerIndex].promote(); 137 if (listener == 0) { 138 mListeners.removeItemsAt(listenerIndex, 1); 139 } 140 } 141 } 142 143 if (listener != 0) { 144 listener->onFrameAvailable(frameId, frame); 145 } 146 return OK; 147} 148 149status_t FrameProcessor::processFaceDetect(const CameraMetadata &frame, 150 sp<Camera2Client> &client) { 151 status_t res; 152 ATRACE_CALL(); 153 camera_metadata_ro_entry_t entry; 154 bool enableFaceDetect; 155 int maxFaces; 156 { 157 SharedParameters::Lock l(client->getParameters()); 158 enableFaceDetect = l.mParameters.enableFaceDetect; 159 } 160 entry = frame.find(ANDROID_STATS_FACE_DETECT_MODE); 161 162 // TODO: This should be an error once implementations are compliant 163 if (entry.count == 0) { 164 return OK; 165 } 166 167 uint8_t faceDetectMode = entry.data.u8[0]; 168 169 camera_frame_metadata metadata; 170 Vector<camera_face_t> faces; 171 metadata.number_of_faces = 0; 172 173 if (enableFaceDetect && faceDetectMode != ANDROID_STATS_FACE_DETECTION_OFF) { 174 SharedParameters::Lock l(client->getParameters()); 175 entry = frame.find(ANDROID_STATS_FACE_RECTANGLES); 176 if (entry.count == 0) { 177 ALOGE("%s: Camera %d: Unable to read face rectangles", 178 __FUNCTION__, client->getCameraId()); 179 return res; 180 } 181 metadata.number_of_faces = entry.count / 4; 182 if (metadata.number_of_faces > 183 l.mParameters.fastInfo.maxFaces) { 184 ALOGE("%s: Camera %d: More faces than expected! (Got %d, max %d)", 185 __FUNCTION__, client->getCameraId(), 186 metadata.number_of_faces, l.mParameters.fastInfo.maxFaces); 187 return res; 188 } 189 const int32_t *faceRects = entry.data.i32; 190 191 entry = frame.find(ANDROID_STATS_FACE_SCORES); 192 if (entry.count == 0) { 193 ALOGE("%s: Camera %d: Unable to read face scores", 194 __FUNCTION__, client->getCameraId()); 195 return res; 196 } 197 const uint8_t *faceScores = entry.data.u8; 198 199 const int32_t *faceLandmarks = NULL; 200 const int32_t *faceIds = NULL; 201 202 if (faceDetectMode == ANDROID_STATS_FACE_DETECTION_FULL) { 203 entry = frame.find(ANDROID_STATS_FACE_LANDMARKS); 204 if (entry.count == 0) { 205 ALOGE("%s: Camera %d: Unable to read face landmarks", 206 __FUNCTION__, client->getCameraId()); 207 return res; 208 } 209 faceLandmarks = entry.data.i32; 210 211 entry = frame.find(ANDROID_STATS_FACE_IDS); 212 213 if (entry.count == 0) { 214 ALOGE("%s: Camera %d: Unable to read face IDs", 215 __FUNCTION__, client->getCameraId()); 216 return res; 217 } 218 faceIds = entry.data.i32; 219 } 220 221 faces.setCapacity(metadata.number_of_faces); 222 223 size_t maxFaces = metadata.number_of_faces; 224 for (size_t i = 0; i < maxFaces; i++) { 225 if (faceScores[i] == 0) { 226 metadata.number_of_faces--; 227 continue; 228 } 229 230 camera_face_t face; 231 232 face.rect[0] = l.mParameters.arrayXToNormalized(faceRects[i*4 + 0]); 233 face.rect[1] = l.mParameters.arrayYToNormalized(faceRects[i*4 + 1]); 234 face.rect[2] = l.mParameters.arrayXToNormalized(faceRects[i*4 + 2]); 235 face.rect[3] = l.mParameters.arrayYToNormalized(faceRects[i*4 + 3]); 236 237 face.score = faceScores[i]; 238 if (faceDetectMode == ANDROID_STATS_FACE_DETECTION_FULL) { 239 face.id = faceIds[i]; 240 face.left_eye[0] = 241 l.mParameters.arrayXToNormalized(faceLandmarks[i*6 + 0]); 242 face.left_eye[1] = 243 l.mParameters.arrayYToNormalized(faceLandmarks[i*6 + 1]); 244 face.right_eye[0] = 245 l.mParameters.arrayXToNormalized(faceLandmarks[i*6 + 2]); 246 face.right_eye[1] = 247 l.mParameters.arrayYToNormalized(faceLandmarks[i*6 + 3]); 248 face.mouth[0] = 249 l.mParameters.arrayXToNormalized(faceLandmarks[i*6 + 4]); 250 face.mouth[1] = 251 l.mParameters.arrayYToNormalized(faceLandmarks[i*6 + 5]); 252 } else { 253 face.id = 0; 254 face.left_eye[0] = face.left_eye[1] = -2000; 255 face.right_eye[0] = face.right_eye[1] = -2000; 256 face.mouth[0] = face.mouth[1] = -2000; 257 } 258 faces.push_back(face); 259 } 260 261 metadata.faces = faces.editArray(); 262 } 263 264 if (metadata.number_of_faces != 0) { 265 Camera2Client::SharedCameraClient::Lock l(client->mSharedCameraClient); 266 if (l.mCameraClient != NULL) { 267 l.mCameraClient->dataCallback(CAMERA_MSG_PREVIEW_METADATA, 268 NULL, &metadata); 269 } 270 } 271 return OK; 272} 273 274}; // namespace camera2 275}; // namespace android 276