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
17852c381dbd1a9f86e6759201b50ac8847a1c3e3cEino-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
247b82efe7a376c882f8f938e1c41b8311a8cdda4aEino-Ville Talvala#include "common/CameraDeviceBase.h"
257b82efe7a376c882f8f938e1c41b8311a8cdda4aEino-Ville Talvala#include "api1/Camera2Client.h"
267b82efe7a376c882f8f938e1c41b8311a8cdda4aEino-Ville Talvala#include "api1/client2/FrameProcessor.h"
27a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala
28a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvalanamespace android {
29a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvalanamespace camera2 {
30a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala
3171381051e2d048b2705c447b3d59db6e972493eeIgor MurashkinFrameProcessor::FrameProcessor(wp<CameraDeviceBase> device,
32fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala                               sp<Camera2Client> client) :
337b82efe7a376c882f8f938e1c41b8311a8cdda4aEino-Ville Talvala    FrameProcessorBase(device),
3471381051e2d048b2705c447b3d59db6e972493eeIgor Murashkin    mClient(client),
35fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala    mLastFrameNumberOfFaces(0),
36fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala    mLast3AFrameNumber(-1) {
3746910bdc57c35ac36bd4adcbb76f4f3a590e3f21Eino-Ville Talvala
3846910bdc57c35ac36bd4adcbb76f4f3a590e3f21Eino-Ville Talvala    sp<CameraDeviceBase> d = device.promote();
3946910bdc57c35ac36bd4adcbb76f4f3a590e3f21Eino-Ville Talvala    mSynthesize3ANotify = !(d->willNotify3A());
40fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala
41fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala    {
42fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala        SharedParameters::Lock l(client->getParameters());
43204e3295e2814052aef7e45ee9edd60128efbbd0Zhijun He
447e8d4590f75afc2b271e7d2e5762ac43d56728dbEmilian Peev        mUsePartialResult = (mNumPartialResults > 1);
45fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala
46fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala        // Initialize starting 3A state
47fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala        m3aState.afTriggerId = l.mParameters.afTriggerCounter;
48fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala        m3aState.aeTriggerId = l.mParameters.precaptureTriggerCounter;
49fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala        // Check if lens is fixed-focus
50fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala        if (l.mParameters.focusMode == Parameters::FOCUS_MODE_FIXED) {
51fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala            m3aState.afMode = ANDROID_CONTROL_AF_MODE_OFF;
525cd8d64b36e0bc87115a5221b06e2fe3c5f9879bChien-Yu Chen        } else {
535cd8d64b36e0bc87115a5221b06e2fe3c5f9879bChien-Yu Chen            m3aState.afMode = ANDROID_CONTROL_AF_MODE_AUTO;
54fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala        }
555cd8d64b36e0bc87115a5221b06e2fe3c5f9879bChien-Yu Chen        m3aState.awbMode = ANDROID_CONTROL_AWB_MODE_AUTO;
565cd8d64b36e0bc87115a5221b06e2fe3c5f9879bChien-Yu Chen        m3aState.aeState = ANDROID_CONTROL_AE_STATE_INACTIVE;
575cd8d64b36e0bc87115a5221b06e2fe3c5f9879bChien-Yu Chen        m3aState.afState = ANDROID_CONTROL_AF_STATE_INACTIVE;
585cd8d64b36e0bc87115a5221b06e2fe3c5f9879bChien-Yu Chen        m3aState.awbState = ANDROID_CONTROL_AWB_STATE_INACTIVE;
59fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala    }
60a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala}
61a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala
62a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville TalvalaFrameProcessor::~FrameProcessor() {
63a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala}
64a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala
65cb0652e5a850b2fcd919e977247e87239efaf70eJianing Weibool FrameProcessor::processSingleFrame(CaptureResult &frame,
6671381051e2d048b2705c447b3d59db6e972493eeIgor Murashkin                                        const sp<CameraDeviceBase> &device) {
6769230df9905534cda15becd44c0109874c4be5f0Eino-Ville Talvala
6871381051e2d048b2705c447b3d59db6e972493eeIgor Murashkin    sp<Camera2Client> client = mClient.promote();
6971381051e2d048b2705c447b3d59db6e972493eeIgor Murashkin    if (!client.get()) {
7071381051e2d048b2705c447b3d59db6e972493eeIgor Murashkin        return false;
714c9eb718352697cd75269752344c0bcc6b05e708Eino-Ville Talvala    }
7269230df9905534cda15becd44c0109874c4be5f0Eino-Ville Talvala
73204e3295e2814052aef7e45ee9edd60128efbbd0Zhijun He    bool isPartialResult = false;
74204e3295e2814052aef7e45ee9edd60128efbbd0Zhijun He    if (mUsePartialResult) {
757e8d4590f75afc2b271e7d2e5762ac43d56728dbEmilian Peev        isPartialResult = frame.mResultExtras.partialResultCount < mNumPartialResults;
76fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala    }
77fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala
78204e3295e2814052aef7e45ee9edd60128efbbd0Zhijun He    if (!isPartialResult && processFaceDetect(frame.mMetadata, client) != OK) {
7971381051e2d048b2705c447b3d59db6e972493eeIgor Murashkin        return false;
80a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala    }
81a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala
8246910bdc57c35ac36bd4adcbb76f4f3a590e3f21Eino-Ville Talvala    if (mSynthesize3ANotify) {
83741ace8776f052245e33a47a0b99400f75996f45Yin-Chia Yeh        process3aState(frame, client);
8446910bdc57c35ac36bd4adcbb76f4f3a590e3f21Eino-Ville Talvala    }
8546910bdc57c35ac36bd4adcbb76f4f3a590e3f21Eino-Ville Talvala
86fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala    return FrameProcessorBase::processSingleFrame(frame, device);
87a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala}
88a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala
8969230df9905534cda15becd44c0109874c4be5f0Eino-Ville Talvalastatus_t FrameProcessor::processFaceDetect(const CameraMetadata &frame,
9071381051e2d048b2705c447b3d59db6e972493eeIgor Murashkin        const sp<Camera2Client> &client) {
9146dee9da04e80971c93cf23d772355217c88bb6aIgor Murashkin    status_t res = BAD_VALUE;
9269230df9905534cda15becd44c0109874c4be5f0Eino-Ville Talvala    ATRACE_CALL();
93a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala    camera_metadata_ro_entry_t entry;
94a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala    bool enableFaceDetect;
95ebe3f69ef09777001b14a1cb9a2a21090655a14bIgor Murashkin
96a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala    {
97a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala        SharedParameters::Lock l(client->getParameters());
98a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala        enableFaceDetect = l.mParameters.enableFaceDetect;
99a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala    }
1002d2b40b67515208273197ac2f03c5fabd430efaeIgor Murashkin    entry = frame.find(ANDROID_STATISTICS_FACE_DETECT_MODE);
101a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala
102a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala    // TODO: This should be an error once implementations are compliant
103a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala    if (entry.count == 0) {
104a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala        return OK;
105a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala    }
106a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala
107a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala    uint8_t faceDetectMode = entry.data.u8[0];
108a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala
109a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala    camera_frame_metadata metadata;
110a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala    Vector<camera_face_t> faces;
111a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala    metadata.number_of_faces = 0;
112a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala
11371381051e2d048b2705c447b3d59db6e972493eeIgor Murashkin    if (enableFaceDetect &&
11471381051e2d048b2705c447b3d59db6e972493eeIgor Murashkin        faceDetectMode != ANDROID_STATISTICS_FACE_DETECT_MODE_OFF) {
11571381051e2d048b2705c447b3d59db6e972493eeIgor Murashkin
116a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala        SharedParameters::Lock l(client->getParameters());
1172d2b40b67515208273197ac2f03c5fabd430efaeIgor Murashkin        entry = frame.find(ANDROID_STATISTICS_FACE_RECTANGLES);
118a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala        if (entry.count == 0) {
1190e0a14013dc3c0c02f96ec486d70d0871747062cEino-Ville Talvala            // No faces this frame
120a2e203bdb911bd5595723651d06ad91c330a7873Igor Murashkin            /* warning: locks SharedCameraCallbacks */
12146dee9da04e80971c93cf23d772355217c88bb6aIgor Murashkin            callbackFaceDetection(client, metadata);
12246dee9da04e80971c93cf23d772355217c88bb6aIgor Murashkin            return OK;
123a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala        }
124a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala        metadata.number_of_faces = entry.count / 4;
125a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala        if (metadata.number_of_faces >
126a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala                l.mParameters.fastInfo.maxFaces) {
127a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala            ALOGE("%s: Camera %d: More faces than expected! (Got %d, max %d)",
128a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala                    __FUNCTION__, client->getCameraId(),
129a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala                    metadata.number_of_faces, l.mParameters.fastInfo.maxFaces);
130a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala            return res;
131a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala        }
132a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala        const int32_t *faceRects = entry.data.i32;
133a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala
1342d2b40b67515208273197ac2f03c5fabd430efaeIgor Murashkin        entry = frame.find(ANDROID_STATISTICS_FACE_SCORES);
135a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala        if (entry.count == 0) {
136a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala            ALOGE("%s: Camera %d: Unable to read face scores",
137a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala                    __FUNCTION__, client->getCameraId());
138a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala            return res;
139a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala        }
140a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala        const uint8_t *faceScores = entry.data.u8;
141a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala
142a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala        const int32_t *faceLandmarks = NULL;
143a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala        const int32_t *faceIds = NULL;
144a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala
1452d2b40b67515208273197ac2f03c5fabd430efaeIgor Murashkin        if (faceDetectMode == ANDROID_STATISTICS_FACE_DETECT_MODE_FULL) {
1462d2b40b67515208273197ac2f03c5fabd430efaeIgor Murashkin            entry = frame.find(ANDROID_STATISTICS_FACE_LANDMARKS);
147a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala            if (entry.count == 0) {
148a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala                ALOGE("%s: Camera %d: Unable to read face landmarks",
149a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala                        __FUNCTION__, client->getCameraId());
150a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala                return res;
151a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala            }
152a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala            faceLandmarks = entry.data.i32;
153a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala
1542d2b40b67515208273197ac2f03c5fabd430efaeIgor Murashkin            entry = frame.find(ANDROID_STATISTICS_FACE_IDS);
155a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala
156a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala            if (entry.count == 0) {
157a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala                ALOGE("%s: Camera %d: Unable to read face IDs",
158a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala                        __FUNCTION__, client->getCameraId());
159a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala                return res;
160a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala            }
161a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala            faceIds = entry.data.i32;
162a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala        }
163a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala
1645e15b80e801a0110bc1bad1190f02cb9c7d22e37Chien-Yu Chen        entry = frame.find(ANDROID_SCALER_CROP_REGION);
1655e15b80e801a0110bc1bad1190f02cb9c7d22e37Chien-Yu Chen        if (entry.count < 4) {
166d309fb9c8a2c4564d88fffba19c4e3688e4b862bEino-Ville Talvala            ALOGE("%s: Camera %d: Unable to read crop region (count = %zu)",
1675e15b80e801a0110bc1bad1190f02cb9c7d22e37Chien-Yu Chen                    __FUNCTION__, client->getCameraId(), entry.count);
1685e15b80e801a0110bc1bad1190f02cb9c7d22e37Chien-Yu Chen            return res;
1695e15b80e801a0110bc1bad1190f02cb9c7d22e37Chien-Yu Chen        }
1705e15b80e801a0110bc1bad1190f02cb9c7d22e37Chien-Yu Chen
1715e15b80e801a0110bc1bad1190f02cb9c7d22e37Chien-Yu Chen        Parameters::CropRegion scalerCrop = {
1725e15b80e801a0110bc1bad1190f02cb9c7d22e37Chien-Yu Chen            static_cast<float>(entry.data.i32[0]),
1735e15b80e801a0110bc1bad1190f02cb9c7d22e37Chien-Yu Chen            static_cast<float>(entry.data.i32[1]),
1745e15b80e801a0110bc1bad1190f02cb9c7d22e37Chien-Yu Chen            static_cast<float>(entry.data.i32[2]),
1755e15b80e801a0110bc1bad1190f02cb9c7d22e37Chien-Yu Chen            static_cast<float>(entry.data.i32[3])};
1765e15b80e801a0110bc1bad1190f02cb9c7d22e37Chien-Yu Chen
177a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala        faces.setCapacity(metadata.number_of_faces);
178a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala
17955619ef9beb0383b383f185f2e1b61a82745dbcdEino-Ville Talvala        size_t maxFaces = metadata.number_of_faces;
18055619ef9beb0383b383f185f2e1b61a82745dbcdEino-Ville Talvala        for (size_t i = 0; i < maxFaces; i++) {
18155619ef9beb0383b383f185f2e1b61a82745dbcdEino-Ville Talvala            if (faceScores[i] == 0) {
18255619ef9beb0383b383f185f2e1b61a82745dbcdEino-Ville Talvala                metadata.number_of_faces--;
18355619ef9beb0383b383f185f2e1b61a82745dbcdEino-Ville Talvala                continue;
18455619ef9beb0383b383f185f2e1b61a82745dbcdEino-Ville Talvala            }
18536185a4b38d43b712dc9790513b8ef5637aab004Alex Ray            if (faceScores[i] > 100) {
186e5729fac81c8a984e984fefc90afc64135817d4fColin Cross                ALOGW("%s: Face index %zu with out of range score %d",
18736185a4b38d43b712dc9790513b8ef5637aab004Alex Ray                        __FUNCTION__, i, faceScores[i]);
18836185a4b38d43b712dc9790513b8ef5637aab004Alex Ray            }
18955619ef9beb0383b383f185f2e1b61a82745dbcdEino-Ville Talvala
190a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala            camera_face_t face;
191a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala
1925e15b80e801a0110bc1bad1190f02cb9c7d22e37Chien-Yu Chen            face.rect[0] = l.mParameters.arrayXToNormalizedWithCrop(
1935e15b80e801a0110bc1bad1190f02cb9c7d22e37Chien-Yu Chen                                faceRects[i*4 + 0], scalerCrop);
1945e15b80e801a0110bc1bad1190f02cb9c7d22e37Chien-Yu Chen            face.rect[1] = l.mParameters.arrayYToNormalizedWithCrop(
1955e15b80e801a0110bc1bad1190f02cb9c7d22e37Chien-Yu Chen                                faceRects[i*4 + 1], scalerCrop);
1965e15b80e801a0110bc1bad1190f02cb9c7d22e37Chien-Yu Chen            face.rect[2] = l.mParameters.arrayXToNormalizedWithCrop(
1975e15b80e801a0110bc1bad1190f02cb9c7d22e37Chien-Yu Chen                                faceRects[i*4 + 2], scalerCrop);
1985e15b80e801a0110bc1bad1190f02cb9c7d22e37Chien-Yu Chen            face.rect[3] = l.mParameters.arrayYToNormalizedWithCrop(
1995e15b80e801a0110bc1bad1190f02cb9c7d22e37Chien-Yu Chen                                faceRects[i*4 + 3], scalerCrop);
200a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala
201a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala            face.score = faceScores[i];
2022d2b40b67515208273197ac2f03c5fabd430efaeIgor Murashkin            if (faceDetectMode == ANDROID_STATISTICS_FACE_DETECT_MODE_FULL) {
203a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala                face.id = faceIds[i];
2045e15b80e801a0110bc1bad1190f02cb9c7d22e37Chien-Yu Chen                face.left_eye[0] = l.mParameters.arrayXToNormalizedWithCrop(
2055e15b80e801a0110bc1bad1190f02cb9c7d22e37Chien-Yu Chen                        faceLandmarks[i*6 + 0], scalerCrop);
2065e15b80e801a0110bc1bad1190f02cb9c7d22e37Chien-Yu Chen                face.left_eye[1] = l.mParameters.arrayYToNormalizedWithCrop(
2075e15b80e801a0110bc1bad1190f02cb9c7d22e37Chien-Yu Chen                        faceLandmarks[i*6 + 1], scalerCrop);
2085e15b80e801a0110bc1bad1190f02cb9c7d22e37Chien-Yu Chen                face.right_eye[0] = l.mParameters.arrayXToNormalizedWithCrop(
2095e15b80e801a0110bc1bad1190f02cb9c7d22e37Chien-Yu Chen                        faceLandmarks[i*6 + 2], scalerCrop);
2105e15b80e801a0110bc1bad1190f02cb9c7d22e37Chien-Yu Chen                face.right_eye[1] = l.mParameters.arrayYToNormalizedWithCrop(
2115e15b80e801a0110bc1bad1190f02cb9c7d22e37Chien-Yu Chen                        faceLandmarks[i*6 + 3], scalerCrop);
2125e15b80e801a0110bc1bad1190f02cb9c7d22e37Chien-Yu Chen                face.mouth[0] = l.mParameters.arrayXToNormalizedWithCrop(
2135e15b80e801a0110bc1bad1190f02cb9c7d22e37Chien-Yu Chen                        faceLandmarks[i*6 + 4], scalerCrop);
2145e15b80e801a0110bc1bad1190f02cb9c7d22e37Chien-Yu Chen                face.mouth[1] = l.mParameters.arrayYToNormalizedWithCrop(
2155e15b80e801a0110bc1bad1190f02cb9c7d22e37Chien-Yu Chen                        faceLandmarks[i*6 + 5], scalerCrop);
216a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala            } else {
217a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala                face.id = 0;
218a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala                face.left_eye[0] = face.left_eye[1] = -2000;
219a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala                face.right_eye[0] = face.right_eye[1] = -2000;
220a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala                face.mouth[0] = face.mouth[1] = -2000;
221a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala            }
222a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala            faces.push_back(face);
223a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala        }
224a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala
225a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala        metadata.faces = faces.editArray();
226a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala    }
227a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala
228a2e203bdb911bd5595723651d06ad91c330a7873Igor Murashkin    /* warning: locks SharedCameraCallbacks */
22946dee9da04e80971c93cf23d772355217c88bb6aIgor Murashkin    callbackFaceDetection(client, metadata);
23046dee9da04e80971c93cf23d772355217c88bb6aIgor Murashkin
23146dee9da04e80971c93cf23d772355217c88bb6aIgor Murashkin    return OK;
23246dee9da04e80971c93cf23d772355217c88bb6aIgor Murashkin}
23346dee9da04e80971c93cf23d772355217c88bb6aIgor Murashkin
234741ace8776f052245e33a47a0b99400f75996f45Yin-Chia Yehstatus_t FrameProcessor::process3aState(const CaptureResult &frame,
23546910bdc57c35ac36bd4adcbb76f4f3a590e3f21Eino-Ville Talvala        const sp<Camera2Client> &client) {
23646910bdc57c35ac36bd4adcbb76f4f3a590e3f21Eino-Ville Talvala
23746910bdc57c35ac36bd4adcbb76f4f3a590e3f21Eino-Ville Talvala    ATRACE_CALL();
238741ace8776f052245e33a47a0b99400f75996f45Yin-Chia Yeh    const CameraMetadata &metadata = frame.mMetadata;
23946910bdc57c35ac36bd4adcbb76f4f3a590e3f21Eino-Ville Talvala    camera_metadata_ro_entry_t entry;
240fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala    int cameraId = client->getCameraId();
24146910bdc57c35ac36bd4adcbb76f4f3a590e3f21Eino-Ville Talvala
242741ace8776f052245e33a47a0b99400f75996f45Yin-Chia Yeh    entry = metadata.find(ANDROID_REQUEST_FRAME_COUNT);
24346910bdc57c35ac36bd4adcbb76f4f3a590e3f21Eino-Ville Talvala    int32_t frameNumber = entry.data.i32[0];
24446910bdc57c35ac36bd4adcbb76f4f3a590e3f21Eino-Ville Talvala
245fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala    // Don't send 3A notifications for the same frame number twice
246fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala    if (frameNumber <= mLast3AFrameNumber) {
247fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala        ALOGV("%s: Already sent 3A for frame number %d, skipping",
248fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala                __FUNCTION__, frameNumber);
2495cd8d64b36e0bc87115a5221b06e2fe3c5f9879bChien-Yu Chen
2505cd8d64b36e0bc87115a5221b06e2fe3c5f9879bChien-Yu Chen        // Remove the entry if there is one for this frame number in mPending3AStates.
2515cd8d64b36e0bc87115a5221b06e2fe3c5f9879bChien-Yu Chen        mPending3AStates.removeItem(frameNumber);
252fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala        return OK;
253fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala    }
254fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala
2555cd8d64b36e0bc87115a5221b06e2fe3c5f9879bChien-Yu Chen    AlgState pendingState;
256fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala
2575cd8d64b36e0bc87115a5221b06e2fe3c5f9879bChien-Yu Chen    ssize_t index = mPending3AStates.indexOfKey(frameNumber);
2585cd8d64b36e0bc87115a5221b06e2fe3c5f9879bChien-Yu Chen    if (index != NAME_NOT_FOUND) {
2595cd8d64b36e0bc87115a5221b06e2fe3c5f9879bChien-Yu Chen        pendingState = mPending3AStates.valueAt(index);
2605cd8d64b36e0bc87115a5221b06e2fe3c5f9879bChien-Yu Chen    }
26146910bdc57c35ac36bd4adcbb76f4f3a590e3f21Eino-Ville Talvala
2625cd8d64b36e0bc87115a5221b06e2fe3c5f9879bChien-Yu Chen    // Update 3A states from the result.
2635cd8d64b36e0bc87115a5221b06e2fe3c5f9879bChien-Yu Chen    bool gotAllStates = true;
26446910bdc57c35ac36bd4adcbb76f4f3a590e3f21Eino-Ville Talvala
265fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala    // TODO: Also use AE mode, AE trigger ID
2665cd8d64b36e0bc87115a5221b06e2fe3c5f9879bChien-Yu Chen    gotAllStates &= updatePendingState<uint8_t>(metadata, ANDROID_CONTROL_AF_MODE,
2675cd8d64b36e0bc87115a5221b06e2fe3c5f9879bChien-Yu Chen            &pendingState.afMode, frameNumber, cameraId);
26846910bdc57c35ac36bd4adcbb76f4f3a590e3f21Eino-Ville Talvala
2695cd8d64b36e0bc87115a5221b06e2fe3c5f9879bChien-Yu Chen    gotAllStates &= updatePendingState<uint8_t>(metadata, ANDROID_CONTROL_AWB_MODE,
2705cd8d64b36e0bc87115a5221b06e2fe3c5f9879bChien-Yu Chen            &pendingState.awbMode, frameNumber, cameraId);
27146910bdc57c35ac36bd4adcbb76f4f3a590e3f21Eino-Ville Talvala
2725cd8d64b36e0bc87115a5221b06e2fe3c5f9879bChien-Yu Chen    gotAllStates &= updatePendingState<uint8_t>(metadata, ANDROID_CONTROL_AE_STATE,
2735cd8d64b36e0bc87115a5221b06e2fe3c5f9879bChien-Yu Chen            &pendingState.aeState, frameNumber, cameraId);
27446910bdc57c35ac36bd4adcbb76f4f3a590e3f21Eino-Ville Talvala
2755cd8d64b36e0bc87115a5221b06e2fe3c5f9879bChien-Yu Chen    gotAllStates &= updatePendingState<uint8_t>(metadata, ANDROID_CONTROL_AF_STATE,
2765cd8d64b36e0bc87115a5221b06e2fe3c5f9879bChien-Yu Chen            &pendingState.afState, frameNumber, cameraId);
27746910bdc57c35ac36bd4adcbb76f4f3a590e3f21Eino-Ville Talvala
2785cd8d64b36e0bc87115a5221b06e2fe3c5f9879bChien-Yu Chen    gotAllStates &= updatePendingState<uint8_t>(metadata, ANDROID_CONTROL_AWB_STATE,
2795cd8d64b36e0bc87115a5221b06e2fe3c5f9879bChien-Yu Chen            &pendingState.awbState, frameNumber, cameraId);
280fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala
2817e8d4590f75afc2b271e7d2e5762ac43d56728dbEmilian Peev    pendingState.afTriggerId = frame.mResultExtras.afTriggerId;
2827e8d4590f75afc2b271e7d2e5762ac43d56728dbEmilian Peev    pendingState.aeTriggerId = frame.mResultExtras.precaptureTriggerId;
28346910bdc57c35ac36bd4adcbb76f4f3a590e3f21Eino-Ville Talvala
2845cd8d64b36e0bc87115a5221b06e2fe3c5f9879bChien-Yu Chen    if (!gotAllStates) {
2855cd8d64b36e0bc87115a5221b06e2fe3c5f9879bChien-Yu Chen        // If not all states are received, put the pending state to mPending3AStates.
2865cd8d64b36e0bc87115a5221b06e2fe3c5f9879bChien-Yu Chen        if (index == NAME_NOT_FOUND) {
2875cd8d64b36e0bc87115a5221b06e2fe3c5f9879bChien-Yu Chen            mPending3AStates.add(frameNumber, pendingState);
2885cd8d64b36e0bc87115a5221b06e2fe3c5f9879bChien-Yu Chen        } else {
2895cd8d64b36e0bc87115a5221b06e2fe3c5f9879bChien-Yu Chen            mPending3AStates.replaceValueAt(index, pendingState);
2905cd8d64b36e0bc87115a5221b06e2fe3c5f9879bChien-Yu Chen        }
2915cd8d64b36e0bc87115a5221b06e2fe3c5f9879bChien-Yu Chen        return NOT_ENOUGH_DATA;
2925cd8d64b36e0bc87115a5221b06e2fe3c5f9879bChien-Yu Chen    }
29346910bdc57c35ac36bd4adcbb76f4f3a590e3f21Eino-Ville Talvala
2945cd8d64b36e0bc87115a5221b06e2fe3c5f9879bChien-Yu Chen    // Once all 3A states are received, notify the client about 3A changes.
2955cd8d64b36e0bc87115a5221b06e2fe3c5f9879bChien-Yu Chen    if (pendingState.aeState != m3aState.aeState) {
296fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala        ALOGV("%s: Camera %d: AE state %d->%d",
297fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala                __FUNCTION__, cameraId,
2985cd8d64b36e0bc87115a5221b06e2fe3c5f9879bChien-Yu Chen                m3aState.aeState, pendingState.aeState);
2995cd8d64b36e0bc87115a5221b06e2fe3c5f9879bChien-Yu Chen        client->notifyAutoExposure(pendingState.aeState, pendingState.aeTriggerId);
30046910bdc57c35ac36bd4adcbb76f4f3a590e3f21Eino-Ville Talvala    }
301fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala
3025cd8d64b36e0bc87115a5221b06e2fe3c5f9879bChien-Yu Chen    if (pendingState.afState != m3aState.afState ||
3035cd8d64b36e0bc87115a5221b06e2fe3c5f9879bChien-Yu Chen        pendingState.afMode != m3aState.afMode ||
3045cd8d64b36e0bc87115a5221b06e2fe3c5f9879bChien-Yu Chen        pendingState.afTriggerId != m3aState.afTriggerId) {
305fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala        ALOGV("%s: Camera %d: AF state %d->%d. AF mode %d->%d. Trigger %d->%d",
306fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala                __FUNCTION__, cameraId,
3075cd8d64b36e0bc87115a5221b06e2fe3c5f9879bChien-Yu Chen                m3aState.afState, pendingState.afState,
3085cd8d64b36e0bc87115a5221b06e2fe3c5f9879bChien-Yu Chen                m3aState.afMode, pendingState.afMode,
3095cd8d64b36e0bc87115a5221b06e2fe3c5f9879bChien-Yu Chen                m3aState.afTriggerId, pendingState.afTriggerId);
3105cd8d64b36e0bc87115a5221b06e2fe3c5f9879bChien-Yu Chen        client->notifyAutoFocus(pendingState.afState, pendingState.afTriggerId);
31146910bdc57c35ac36bd4adcbb76f4f3a590e3f21Eino-Ville Talvala    }
3125cd8d64b36e0bc87115a5221b06e2fe3c5f9879bChien-Yu Chen    if (pendingState.awbState != m3aState.awbState ||
3135cd8d64b36e0bc87115a5221b06e2fe3c5f9879bChien-Yu Chen        pendingState.awbMode != m3aState.awbMode) {
314fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala        ALOGV("%s: Camera %d: AWB state %d->%d. AWB mode %d->%d",
315fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala                __FUNCTION__, cameraId,
3165cd8d64b36e0bc87115a5221b06e2fe3c5f9879bChien-Yu Chen                m3aState.awbState, pendingState.awbState,
3175cd8d64b36e0bc87115a5221b06e2fe3c5f9879bChien-Yu Chen                m3aState.awbMode, pendingState.awbMode);
3185cd8d64b36e0bc87115a5221b06e2fe3c5f9879bChien-Yu Chen        client->notifyAutoWhitebalance(pendingState.awbState,
3195cd8d64b36e0bc87115a5221b06e2fe3c5f9879bChien-Yu Chen                pendingState.aeTriggerId);
32046910bdc57c35ac36bd4adcbb76f4f3a590e3f21Eino-Ville Talvala    }
32146910bdc57c35ac36bd4adcbb76f4f3a590e3f21Eino-Ville Talvala
3225cd8d64b36e0bc87115a5221b06e2fe3c5f9879bChien-Yu Chen    if (index != NAME_NOT_FOUND) {
3235cd8d64b36e0bc87115a5221b06e2fe3c5f9879bChien-Yu Chen        mPending3AStates.removeItemsAt(index);
3245cd8d64b36e0bc87115a5221b06e2fe3c5f9879bChien-Yu Chen    }
3255cd8d64b36e0bc87115a5221b06e2fe3c5f9879bChien-Yu Chen
3265cd8d64b36e0bc87115a5221b06e2fe3c5f9879bChien-Yu Chen    m3aState = pendingState;
3275cd8d64b36e0bc87115a5221b06e2fe3c5f9879bChien-Yu Chen    mLast3AFrameNumber = frameNumber;
32846910bdc57c35ac36bd4adcbb76f4f3a590e3f21Eino-Ville Talvala
32946910bdc57c35ac36bd4adcbb76f4f3a590e3f21Eino-Ville Talvala    return OK;
33046910bdc57c35ac36bd4adcbb76f4f3a590e3f21Eino-Ville Talvala}
33146910bdc57c35ac36bd4adcbb76f4f3a590e3f21Eino-Ville Talvala
332fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvalatemplate<typename Src, typename T>
3335cd8d64b36e0bc87115a5221b06e2fe3c5f9879bChien-Yu Chenbool FrameProcessor::updatePendingState(const CameraMetadata& result, int32_t tag,
334fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala        T* value, int32_t frameNumber, int cameraId) {
335fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala    camera_metadata_ro_entry_t entry;
336fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala    if (value == NULL) {
337fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala        ALOGE("%s: Camera %d: Value to write to is NULL",
338fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala                __FUNCTION__, cameraId);
339fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala        return false;
340fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala    }
341fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala
3425cd8d64b36e0bc87115a5221b06e2fe3c5f9879bChien-Yu Chen    // Already got the value for this tag.
3435cd8d64b36e0bc87115a5221b06e2fe3c5f9879bChien-Yu Chen    if (*value != static_cast<T>(NOT_SET)) {
3445cd8d64b36e0bc87115a5221b06e2fe3c5f9879bChien-Yu Chen        return true;
3455cd8d64b36e0bc87115a5221b06e2fe3c5f9879bChien-Yu Chen    }
3465cd8d64b36e0bc87115a5221b06e2fe3c5f9879bChien-Yu Chen
347fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala    entry = result.find(tag);
348fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala    if (entry.count == 0) {
34971c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev        const camera_metadata *metaBuffer = result.getAndLock();
3505cd8d64b36e0bc87115a5221b06e2fe3c5f9879bChien-Yu Chen        ALOGV("%s: Camera %d: No %s provided by HAL for frame %d in this result!",
351fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala                __FUNCTION__, cameraId,
35271c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev                get_local_camera_metadata_tag_name(tag, metaBuffer),
35371c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev                frameNumber);
35471c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev        result.unlock(metaBuffer);
355fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala        return false;
356fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala    } else {
357fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala        switch(sizeof(Src)){
358fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala            case sizeof(uint8_t):
359fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala                *value = static_cast<T>(entry.data.u8[0]);
360fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala                break;
361fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala            case sizeof(int32_t):
362fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala                *value = static_cast<T>(entry.data.i32[0]);
363fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala                break;
364fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala            default:
365fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala                ALOGE("%s: Camera %d: Unsupported source",
366fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala                        __FUNCTION__, cameraId);
367fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala                return false;
368fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala        }
369fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala    }
370fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala    return true;
371fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala}
372fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala
37346910bdc57c35ac36bd4adcbb76f4f3a590e3f21Eino-Ville Talvala
3748b0b971b1416738f22488a80be726d1ec12552a8Chih-Hung Hsiehvoid FrameProcessor::callbackFaceDetection(const sp<Camera2Client>& client,
37571381051e2d048b2705c447b3d59db6e972493eeIgor Murashkin                                     const camera_frame_metadata &metadata) {
37671381051e2d048b2705c447b3d59db6e972493eeIgor Murashkin
37771381051e2d048b2705c447b3d59db6e972493eeIgor Murashkin    camera_frame_metadata *metadata_ptr =
37871381051e2d048b2705c447b3d59db6e972493eeIgor Murashkin        const_cast<camera_frame_metadata*>(&metadata);
37971381051e2d048b2705c447b3d59db6e972493eeIgor Murashkin
38071381051e2d048b2705c447b3d59db6e972493eeIgor Murashkin    /**
38171381051e2d048b2705c447b3d59db6e972493eeIgor Murashkin     * Filter out repeated 0-face callbacks,
38271381051e2d048b2705c447b3d59db6e972493eeIgor Murashkin     * but not when the last frame was >0
38371381051e2d048b2705c447b3d59db6e972493eeIgor Murashkin     */
38471381051e2d048b2705c447b3d59db6e972493eeIgor Murashkin    if (metadata.number_of_faces != 0 ||
38571381051e2d048b2705c447b3d59db6e972493eeIgor Murashkin        mLastFrameNumberOfFaces != metadata.number_of_faces) {
38646dee9da04e80971c93cf23d772355217c88bb6aIgor Murashkin
38771381051e2d048b2705c447b3d59db6e972493eeIgor Murashkin        Camera2Client::SharedCameraCallbacks::Lock
38871381051e2d048b2705c447b3d59db6e972493eeIgor Murashkin            l(client->mSharedCameraCallbacks);
389a2e203bdb911bd5595723651d06ad91c330a7873Igor Murashkin        if (l.mRemoteCallback != NULL) {
390a2e203bdb911bd5595723651d06ad91c330a7873Igor Murashkin            l.mRemoteCallback->dataCallback(CAMERA_MSG_PREVIEW_METADATA,
39171381051e2d048b2705c447b3d59db6e972493eeIgor Murashkin                                            NULL,
39271381051e2d048b2705c447b3d59db6e972493eeIgor Murashkin                                            metadata_ptr);
393a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala        }
394a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala    }
39546dee9da04e80971c93cf23d772355217c88bb6aIgor Murashkin
39646dee9da04e80971c93cf23d772355217c88bb6aIgor Murashkin    mLastFrameNumberOfFaces = metadata.number_of_faces;
397a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala}
398a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala
399a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala}; // namespace camera2
400a16733eeb9c40db4793bec408f29b4204e5f23b1Eino-Ville Talvala}; // namespace android
401