1a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala/* 2a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala * Copyright (C) 2012 The Android Open Source Project 3a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala * 4a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala * Licensed under the Apache License, Version 2.0 (the "License"); 5a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala * you may not use this file except in compliance with the License. 6a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala * You may obtain a copy of the License at 7a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala * 8a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala * http://www.apache.org/licenses/LICENSE-2.0 9a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala * 10a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala * Unless required by applicable law or agreed to in writing, software 11a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala * distributed under the License is distributed on an "AS IS" BASIS, 12a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala * See the License for the specific language governing permissions and 14a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala * limitations under the License. 15a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala */ 16a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala 174bb8118816874c696d9f1adab48490df1da365f7Eino-Ville Talvala#define LOG_TAG "Camera2-FrameProcessor" 18a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala#define ATRACE_TAG ATRACE_TAG_CAMERA 19a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala//#define LOG_NDEBUG 0 20a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala 21a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala#include <utils/Log.h> 22a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala#include <utils/Trace.h> 23a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala 24a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala#include "FrameProcessor.h" 25a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala#include "../Camera2Device.h" 26a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala#include "../Camera2Client.h" 27a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala 28a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvalanamespace android { 29a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvalanamespace camera2 { 30a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala 31a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville TalvalaFrameProcessor::FrameProcessor(wp<Camera2Client> client): 32e7f256a4b1d2037a67ab139fc8131a6ca97bd405Igor Murashkin Thread(false), mClient(client), mLastFrameNumberOfFaces(0) { 33a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala} 34a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala 35a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville TalvalaFrameProcessor::~FrameProcessor() { 36a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala ALOGV("%s: Exit", __FUNCTION__); 37a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala} 38a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala 394865c526e681366481b0ab242ffa1ead57bb02ccEino-Ville Talvalastatus_t FrameProcessor::registerListener(int32_t minId, 404865c526e681366481b0ab242ffa1ead57bb02ccEino-Ville Talvala int32_t maxId, wp<FilteredListener> listener) { 41da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala Mutex::Autolock l(mInputMutex); 424865c526e681366481b0ab242ffa1ead57bb02ccEino-Ville Talvala ALOGV("%s: Registering listener for frame id range %d - %d", 434865c526e681366481b0ab242ffa1ead57bb02ccEino-Ville Talvala __FUNCTION__, minId, maxId); 444865c526e681366481b0ab242ffa1ead57bb02ccEino-Ville Talvala RangeListener rListener = { minId, maxId, listener }; 454865c526e681366481b0ab242ffa1ead57bb02ccEino-Ville Talvala mRangeListeners.push_back(rListener); 464865c526e681366481b0ab242ffa1ead57bb02ccEino-Ville Talvala return OK; 47da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala} 48da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala 494865c526e681366481b0ab242ffa1ead57bb02ccEino-Ville Talvalastatus_t FrameProcessor::removeListener(int32_t minId, 504865c526e681366481b0ab242ffa1ead57bb02ccEino-Ville Talvala int32_t maxId, wp<FilteredListener> listener) { 51da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala Mutex::Autolock l(mInputMutex); 524865c526e681366481b0ab242ffa1ead57bb02ccEino-Ville Talvala List<RangeListener>::iterator item = mRangeListeners.begin(); 534865c526e681366481b0ab242ffa1ead57bb02ccEino-Ville Talvala while (item != mRangeListeners.end()) { 544865c526e681366481b0ab242ffa1ead57bb02ccEino-Ville Talvala if (item->minId == minId && 554865c526e681366481b0ab242ffa1ead57bb02ccEino-Ville Talvala item->maxId == maxId && 564865c526e681366481b0ab242ffa1ead57bb02ccEino-Ville Talvala item->listener == listener) { 574865c526e681366481b0ab242ffa1ead57bb02ccEino-Ville Talvala item = mRangeListeners.erase(item); 584865c526e681366481b0ab242ffa1ead57bb02ccEino-Ville Talvala } else { 594865c526e681366481b0ab242ffa1ead57bb02ccEino-Ville Talvala item++; 604865c526e681366481b0ab242ffa1ead57bb02ccEino-Ville Talvala } 614865c526e681366481b0ab242ffa1ead57bb02ccEino-Ville Talvala } 624865c526e681366481b0ab242ffa1ead57bb02ccEino-Ville Talvala return OK; 63da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala} 64da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala 65a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvalavoid FrameProcessor::dump(int fd, const Vector<String16>& args) { 66a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala String8 result(" Latest received frame:\n"); 67a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala write(fd, result.string(), result.size()); 68a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala mLastFrame.dump(fd, 2, 6); 69a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala} 70a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala 71a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvalabool FrameProcessor::threadLoop() { 72a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala status_t res; 73a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala 74a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala sp<Camera2Device> device; 75a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala { 76a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala sp<Camera2Client> client = mClient.promote(); 77a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala if (client == 0) return false; 78a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala device = client->getCameraDevice(); 79da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala if (device == 0) return false; 80a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala } 81a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala 82a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala res = device->waitForNextFrame(kWaitDuration); 83a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala if (res == OK) { 84a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala sp<Camera2Client> client = mClient.promote(); 85a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala if (client == 0) return false; 86a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala processNewFrames(client); 87a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala } else if (res != TIMED_OUT) { 88a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala ALOGE("Camera2Client::FrameProcessor: Error waiting for new " 89a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala "frames: %s (%d)", strerror(-res), res); 90a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala } 91a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala 92a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala return true; 93a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala} 94a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala 95a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvalavoid FrameProcessor::processNewFrames(sp<Camera2Client> &client) { 96a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala status_t res; 97da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala ATRACE_CALL(); 98a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala CameraMetadata frame; 99a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala while ( (res = client->getCameraDevice()->getNextFrame(&frame)) == OK) { 100a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala camera_metadata_entry_t entry; 101da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala 102a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala entry = frame.find(ANDROID_REQUEST_FRAME_COUNT); 103a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala if (entry.count == 0) { 104da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala ALOGE("%s: Camera %d: Error reading frame number", 105da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala __FUNCTION__, client->getCameraId()); 106a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala break; 107a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala } 1084bb8118816874c696d9f1adab48490df1da365f7Eino-Ville Talvala ATRACE_INT("cam2_frame", entry.data.i32[0]); 109a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala 110a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala res = processFaceDetect(frame, client); 111a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala if (res != OK) break; 112a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala 1134865c526e681366481b0ab242ffa1ead57bb02ccEino-Ville Talvala res = processListeners(frame, client); 114da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala if (res != OK) break; 115da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala 116da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala if (!frame.isEmpty()) { 117da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala mLastFrame.acquire(frame); 118da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala } 119a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala } 120a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala if (res != NOT_ENOUGH_DATA) { 121a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala ALOGE("%s: Camera %d: Error getting next frame: %s (%d)", 122a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala __FUNCTION__, client->getCameraId(), strerror(-res), res); 123a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala return; 124a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala } 125a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala 126a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala return; 127a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala} 128a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala 1294865c526e681366481b0ab242ffa1ead57bb02ccEino-Ville Talvalastatus_t FrameProcessor::processListeners(const CameraMetadata &frame, 130da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala sp<Camera2Client> &client) { 131da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala status_t res; 132da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala ATRACE_CALL(); 1334865c526e681366481b0ab242ffa1ead57bb02ccEino-Ville Talvala camera_metadata_ro_entry_t entry; 134da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala 135da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala entry = frame.find(ANDROID_REQUEST_ID); 136da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala if (entry.count == 0) { 137da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala ALOGE("%s: Camera %d: Error reading frame id", 138da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala __FUNCTION__, client->getCameraId()); 139da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala return BAD_VALUE; 140da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala } 141da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala int32_t frameId = entry.data.i32[0]; 142da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala 1434865c526e681366481b0ab242ffa1ead57bb02ccEino-Ville Talvala List<sp<FilteredListener> > listeners; 144da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala { 145da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala Mutex::Autolock l(mInputMutex); 1464865c526e681366481b0ab242ffa1ead57bb02ccEino-Ville Talvala 1474865c526e681366481b0ab242ffa1ead57bb02ccEino-Ville Talvala List<RangeListener>::iterator item = mRangeListeners.begin(); 1484865c526e681366481b0ab242ffa1ead57bb02ccEino-Ville Talvala while (item != mRangeListeners.end()) { 1494865c526e681366481b0ab242ffa1ead57bb02ccEino-Ville Talvala if (frameId >= item->minId && 1504865c526e681366481b0ab242ffa1ead57bb02ccEino-Ville Talvala frameId < item->maxId) { 1514865c526e681366481b0ab242ffa1ead57bb02ccEino-Ville Talvala sp<FilteredListener> listener = item->listener.promote(); 1524865c526e681366481b0ab242ffa1ead57bb02ccEino-Ville Talvala if (listener == 0) { 1534865c526e681366481b0ab242ffa1ead57bb02ccEino-Ville Talvala item = mRangeListeners.erase(item); 1544865c526e681366481b0ab242ffa1ead57bb02ccEino-Ville Talvala continue; 1554865c526e681366481b0ab242ffa1ead57bb02ccEino-Ville Talvala } else { 1564865c526e681366481b0ab242ffa1ead57bb02ccEino-Ville Talvala listeners.push_back(listener); 1574865c526e681366481b0ab242ffa1ead57bb02ccEino-Ville Talvala } 158da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala } 1594865c526e681366481b0ab242ffa1ead57bb02ccEino-Ville Talvala item++; 160da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala } 161da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala } 1624865c526e681366481b0ab242ffa1ead57bb02ccEino-Ville Talvala ALOGV("Got %d range listeners out of %d", listeners.size(), mRangeListeners.size()); 1634865c526e681366481b0ab242ffa1ead57bb02ccEino-Ville Talvala List<sp<FilteredListener> >::iterator item = listeners.begin(); 1644865c526e681366481b0ab242ffa1ead57bb02ccEino-Ville Talvala for (; item != listeners.end(); item++) { 1654865c526e681366481b0ab242ffa1ead57bb02ccEino-Ville Talvala (*item)->onFrameAvailable(frameId, frame); 166da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala } 167da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala return OK; 168da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala} 169da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala 170da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvalastatus_t FrameProcessor::processFaceDetect(const CameraMetadata &frame, 171da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala sp<Camera2Client> &client) { 172e7f256a4b1d2037a67ab139fc8131a6ca97bd405Igor Murashkin status_t res = BAD_VALUE; 173da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala ATRACE_CALL(); 174a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala camera_metadata_ro_entry_t entry; 175a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala bool enableFaceDetect; 176a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala int maxFaces; 177a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala { 178a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala SharedParameters::Lock l(client->getParameters()); 179a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala enableFaceDetect = l.mParameters.enableFaceDetect; 180a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala } 181a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala entry = frame.find(ANDROID_STATS_FACE_DETECT_MODE); 182a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala 183a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala // TODO: This should be an error once implementations are compliant 184a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala if (entry.count == 0) { 185a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala return OK; 186a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala } 187a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala 188a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala uint8_t faceDetectMode = entry.data.u8[0]; 189a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala 190a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala camera_frame_metadata metadata; 191a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala Vector<camera_face_t> faces; 192a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala metadata.number_of_faces = 0; 193a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala 194a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala if (enableFaceDetect && faceDetectMode != ANDROID_STATS_FACE_DETECTION_OFF) { 195a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala SharedParameters::Lock l(client->getParameters()); 196a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala entry = frame.find(ANDROID_STATS_FACE_RECTANGLES); 197a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala if (entry.count == 0) { 198663c2cd909cb9c0699b4d58c1db7c6252afd77eaEino-Ville Talvala // No faces this frame 199e7f256a4b1d2037a67ab139fc8131a6ca97bd405Igor Murashkin /* warning: locks SharedCameraClient */ 200e7f256a4b1d2037a67ab139fc8131a6ca97bd405Igor Murashkin callbackFaceDetection(client, metadata); 201e7f256a4b1d2037a67ab139fc8131a6ca97bd405Igor Murashkin return OK; 202a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala } 203a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala metadata.number_of_faces = entry.count / 4; 204a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala if (metadata.number_of_faces > 205a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala l.mParameters.fastInfo.maxFaces) { 206a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala ALOGE("%s: Camera %d: More faces than expected! (Got %d, max %d)", 207a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala __FUNCTION__, client->getCameraId(), 208a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala metadata.number_of_faces, l.mParameters.fastInfo.maxFaces); 209a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala return res; 210a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala } 211a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala const int32_t *faceRects = entry.data.i32; 212a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala 213a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala entry = frame.find(ANDROID_STATS_FACE_SCORES); 214a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala if (entry.count == 0) { 215a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala ALOGE("%s: Camera %d: Unable to read face scores", 216a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala __FUNCTION__, client->getCameraId()); 217a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala return res; 218a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala } 219a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala const uint8_t *faceScores = entry.data.u8; 220a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala 221a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala const int32_t *faceLandmarks = NULL; 222a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala const int32_t *faceIds = NULL; 223a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala 224a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala if (faceDetectMode == ANDROID_STATS_FACE_DETECTION_FULL) { 225a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala entry = frame.find(ANDROID_STATS_FACE_LANDMARKS); 226a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala if (entry.count == 0) { 227a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala ALOGE("%s: Camera %d: Unable to read face landmarks", 228a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala __FUNCTION__, client->getCameraId()); 229a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala return res; 230a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala } 231a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala faceLandmarks = entry.data.i32; 232a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala 233a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala entry = frame.find(ANDROID_STATS_FACE_IDS); 234a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala 235a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala if (entry.count == 0) { 236a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala ALOGE("%s: Camera %d: Unable to read face IDs", 237a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala __FUNCTION__, client->getCameraId()); 238a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala return res; 239a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala } 240a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala faceIds = entry.data.i32; 241a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala } 242a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala 243a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala faces.setCapacity(metadata.number_of_faces); 244a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala 245a9f8d040146533a9c214473fd79cbd9dff44428dEino-Ville Talvala size_t maxFaces = metadata.number_of_faces; 246a9f8d040146533a9c214473fd79cbd9dff44428dEino-Ville Talvala for (size_t i = 0; i < maxFaces; i++) { 247a9f8d040146533a9c214473fd79cbd9dff44428dEino-Ville Talvala if (faceScores[i] == 0) { 248a9f8d040146533a9c214473fd79cbd9dff44428dEino-Ville Talvala metadata.number_of_faces--; 249a9f8d040146533a9c214473fd79cbd9dff44428dEino-Ville Talvala continue; 250a9f8d040146533a9c214473fd79cbd9dff44428dEino-Ville Talvala } 251a9f8d040146533a9c214473fd79cbd9dff44428dEino-Ville Talvala 252a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala camera_face_t face; 253a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala 254a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala face.rect[0] = l.mParameters.arrayXToNormalized(faceRects[i*4 + 0]); 255a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala face.rect[1] = l.mParameters.arrayYToNormalized(faceRects[i*4 + 1]); 256a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala face.rect[2] = l.mParameters.arrayXToNormalized(faceRects[i*4 + 2]); 257a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala face.rect[3] = l.mParameters.arrayYToNormalized(faceRects[i*4 + 3]); 258a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala 259a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala face.score = faceScores[i]; 260a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala if (faceDetectMode == ANDROID_STATS_FACE_DETECTION_FULL) { 261a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala face.id = faceIds[i]; 262a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala face.left_eye[0] = 263a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala l.mParameters.arrayXToNormalized(faceLandmarks[i*6 + 0]); 264a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala face.left_eye[1] = 265a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala l.mParameters.arrayYToNormalized(faceLandmarks[i*6 + 1]); 266a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala face.right_eye[0] = 267a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala l.mParameters.arrayXToNormalized(faceLandmarks[i*6 + 2]); 268a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala face.right_eye[1] = 269a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala l.mParameters.arrayYToNormalized(faceLandmarks[i*6 + 3]); 270a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala face.mouth[0] = 271a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala l.mParameters.arrayXToNormalized(faceLandmarks[i*6 + 4]); 272a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala face.mouth[1] = 273a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala l.mParameters.arrayYToNormalized(faceLandmarks[i*6 + 5]); 274a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala } else { 275a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala face.id = 0; 276a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala face.left_eye[0] = face.left_eye[1] = -2000; 277a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala face.right_eye[0] = face.right_eye[1] = -2000; 278a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala face.mouth[0] = face.mouth[1] = -2000; 279a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala } 280a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala faces.push_back(face); 281a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala } 282a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala 283a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala metadata.faces = faces.editArray(); 284a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala } 285a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala 286e7f256a4b1d2037a67ab139fc8131a6ca97bd405Igor Murashkin /* warning: locks SharedCameraClient */ 287e7f256a4b1d2037a67ab139fc8131a6ca97bd405Igor Murashkin callbackFaceDetection(client, metadata); 288e7f256a4b1d2037a67ab139fc8131a6ca97bd405Igor Murashkin 289e7f256a4b1d2037a67ab139fc8131a6ca97bd405Igor Murashkin return OK; 290e7f256a4b1d2037a67ab139fc8131a6ca97bd405Igor Murashkin} 291e7f256a4b1d2037a67ab139fc8131a6ca97bd405Igor Murashkin 292e7f256a4b1d2037a67ab139fc8131a6ca97bd405Igor Murashkinvoid FrameProcessor::callbackFaceDetection(sp<Camera2Client> client, 293e7f256a4b1d2037a67ab139fc8131a6ca97bd405Igor Murashkin /*in*/camera_frame_metadata &metadata) { 294e7f256a4b1d2037a67ab139fc8131a6ca97bd405Igor Murashkin 295e7f256a4b1d2037a67ab139fc8131a6ca97bd405Igor Murashkin /* Filter out repeated 0-face callbacks, but not when the last frame was >0 */ 296e7f256a4b1d2037a67ab139fc8131a6ca97bd405Igor Murashkin if (metadata.number_of_faces != 0 || mLastFrameNumberOfFaces != metadata.number_of_faces) { 297a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala Camera2Client::SharedCameraClient::Lock l(client->mSharedCameraClient); 298a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala if (l.mCameraClient != NULL) { 299a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala l.mCameraClient->dataCallback(CAMERA_MSG_PREVIEW_METADATA, 300a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala NULL, &metadata); 301a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala } 302a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala } 303e7f256a4b1d2037a67ab139fc8131a6ca97bd405Igor Murashkin 304e7f256a4b1d2037a67ab139fc8131a6ca97bd405Igor Murashkin mLastFrameNumberOfFaces = metadata.number_of_faces; 305a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala} 306a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala 307a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala}; // namespace camera2 308a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala}; // namespace android 309