1da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala/*
2da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala * Copyright (C) 2012 The Android Open Source Project
3da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala *
4da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala * Licensed under the Apache License, Version 2.0 (the "License");
5da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala * you may not use this file except in compliance with the License.
6da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala * You may obtain a copy of the License at
7da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala *
8da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala *      http://www.apache.org/licenses/LICENSE-2.0
9da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala *
10da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala * Unless required by applicable law or agreed to in writing, software
11da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala * distributed under the License is distributed on an "AS IS" BASIS,
12da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala * See the License for the specific language governing permissions and
14da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala * limitations under the License.
15da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala */
16da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala
174bb8118816874c696d9f1adab48490df1da365f7Eino-Ville Talvala#define LOG_TAG "Camera2-ZslProcessor"
18da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala#define ATRACE_TAG ATRACE_TAG_CAMERA
19da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala//#define LOG_NDEBUG 0
20da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala//#define LOG_NNDEBUG 0
21da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala
22da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala#ifdef LOG_NNDEBUG
23da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala#define ALOGVV(...) ALOGV(__VA_ARGS__)
24da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala#else
25da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala#define ALOGVV(...) ((void)0)
26da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala#endif
27da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala
28e5729fac81c8a984e984fefc90afc64135817d4fColin Cross#include <inttypes.h>
29e5729fac81c8a984e984fefc90afc64135817d4fColin Cross
30da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala#include <utils/Log.h>
31da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala#include <utils/Trace.h>
321a2952aee048ca7b1765e2bc09ebe9aeddaeafa3Mathias Agopian#include <gui/Surface.h>
33da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala
347b82efe7a376c882f8f938e1c41b8311a8cdda4aEino-Ville Talvala#include "common/CameraDeviceBase.h"
357b82efe7a376c882f8f938e1c41b8311a8cdda4aEino-Ville Talvala#include "api1/Camera2Client.h"
367b82efe7a376c882f8f938e1c41b8311a8cdda4aEino-Ville Talvala#include "api1/client2/CaptureSequencer.h"
377b82efe7a376c882f8f938e1c41b8311a8cdda4aEino-Ville Talvala#include "api1/client2/ZslProcessor.h"
38da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala
39da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvalanamespace android {
40da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvalanamespace camera2 {
41da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala
42da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville TalvalaZslProcessor::ZslProcessor(
43d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala    sp<Camera2Client> client,
44da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala    wp<CaptureSequencer> sequencer):
45da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala        Thread(false),
46da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala        mState(RUNNING),
47da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala        mClient(client),
48d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala        mDevice(client->getCameraDevice()),
49da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala        mSequencer(sequencer),
50d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala        mId(client->getCameraId()),
516551e1ede59f4a3043fb141159ca67bd2c85a911Ruben Brunk        mDeleted(false),
52da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala        mZslBufferAvailable(false),
53da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala        mZslStreamId(NO_STREAM),
54da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala        mZslReprocessStreamId(NO_STREAM),
55da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala        mFrameListHead(0),
56da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala        mZslQueueHead(0),
57da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala        mZslQueueTail(0) {
58da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala    mZslQueue.insertAt(0, kZslBufferDepth);
59da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala    mFrameList.insertAt(0, kFrameListDepth);
60da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala    sp<CaptureSequencer> captureSequencer = mSequencer.promote();
61da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala    if (captureSequencer != 0) captureSequencer->setZslProcessor(this);
62da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala}
63da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala
64da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville TalvalaZslProcessor::~ZslProcessor() {
65da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala    ALOGV("%s: Exit", __FUNCTION__);
666551e1ede59f4a3043fb141159ca67bd2c85a911Ruben Brunk    disconnect();
67da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala}
68da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala
6904f101c35eaa90b1f95939afac30674ec1611e6fDan Stozavoid ZslProcessor::onFrameAvailable(const BufferItem& /*item*/) {
70da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala    Mutex::Autolock l(mInputMutex);
71da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala    if (!mZslBufferAvailable) {
72da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala        mZslBufferAvailable = true;
73da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala        mZslBufferAvailableSignal.signal();
74da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala    }
75da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala}
76da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala
77cb0652e5a850b2fcd919e977247e87239efaf70eJianing Weivoid ZslProcessor::onResultAvailable(const CaptureResult &result) {
78cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei    ATRACE_CALL();
79cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei    ALOGV("%s:", __FUNCTION__);
80da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala    Mutex::Autolock l(mInputMutex);
814865c526e681366481b0ab242ffa1ead57bb02ccEino-Ville Talvala    camera_metadata_ro_entry_t entry;
82cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei    entry = result.mMetadata.find(ANDROID_SENSOR_TIMESTAMP);
83da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala    nsecs_t timestamp = entry.data.i64[0];
84ddf3c5025e2f6f35a4c188c19f30142c64a092c4Igor Murashkin    (void)timestamp;
85e5729fac81c8a984e984fefc90afc64135817d4fColin Cross    ALOGVV("Got preview frame for timestamp %" PRId64, timestamp);
86da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala
87da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala    if (mState != RUNNING) return;
88da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala
89cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei    mFrameList.editItemAt(mFrameListHead) = result.mMetadata;
90da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala    mFrameListHead = (mFrameListHead + 1) % kFrameListDepth;
91da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala
92da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala    findMatchesLocked();
93da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala}
94da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala
95da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvalavoid ZslProcessor::onBufferReleased(buffer_handle_t *handle) {
96da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala    Mutex::Autolock l(mInputMutex);
97da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala
9897b38a81ac989ccba02d726011a82541f14166dfEino-Ville Talvala    // Verify that the buffer is in our queue
9997b38a81ac989ccba02d726011a82541f14166dfEino-Ville Talvala    size_t i = 0;
10097b38a81ac989ccba02d726011a82541f14166dfEino-Ville Talvala    for (; i < mZslQueue.size(); i++) {
10197b38a81ac989ccba02d726011a82541f14166dfEino-Ville Talvala        if (&(mZslQueue[i].buffer.mGraphicBuffer->handle) == handle) break;
10297b38a81ac989ccba02d726011a82541f14166dfEino-Ville Talvala    }
10397b38a81ac989ccba02d726011a82541f14166dfEino-Ville Talvala    if (i == mZslQueue.size()) {
10497b38a81ac989ccba02d726011a82541f14166dfEino-Ville Talvala        ALOGW("%s: Released buffer %p not found in queue",
10597b38a81ac989ccba02d726011a82541f14166dfEino-Ville Talvala                __FUNCTION__, handle);
106da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala    }
107da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala
108768cf093dade9085e0ad6305d9f7c16ae9ad9e26Eino-Ville Talvala    // Erase entire ZSL queue since we've now completed the capture and preview
109768cf093dade9085e0ad6305d9f7c16ae9ad9e26Eino-Ville Talvala    // is stopped.
110768cf093dade9085e0ad6305d9f7c16ae9ad9e26Eino-Ville Talvala    clearZslQueueLocked();
111768cf093dade9085e0ad6305d9f7c16ae9ad9e26Eino-Ville Talvala
112da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala    mState = RUNNING;
113da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala}
114da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala
115da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvalastatus_t ZslProcessor::updateStream(const Parameters &params) {
116da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala    ATRACE_CALL();
117da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala    ALOGV("%s: Configuring ZSL streams", __FUNCTION__);
118da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala    status_t res;
119da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala
120da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala    Mutex::Autolock l(mInputMutex);
121da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala
122da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala    sp<Camera2Client> client = mClient.promote();
123d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala    if (client == 0) {
124d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala        ALOGE("%s: Camera %d: Client does not exist", __FUNCTION__, mId);
125d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala        return INVALID_OPERATION;
126d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala    }
127d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala    sp<CameraDeviceBase> device = mDevice.promote();
128d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala    if (device == 0) {
129d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala        ALOGE("%s: Camera %d: Device does not exist", __FUNCTION__, mId);
130d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala        return INVALID_OPERATION;
131d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala    }
132da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala
133da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala    if (mZslConsumer == 0) {
134da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala        // Create CPU buffer queue endpoint
1358aa0f0619ea867e8fb240cf27913d4f8ae767385Dan Stoza        sp<IGraphicBufferProducer> producer;
1368aa0f0619ea867e8fb240cf27913d4f8ae767385Dan Stoza        sp<IGraphicBufferConsumer> consumer;
1378aa0f0619ea867e8fb240cf27913d4f8ae767385Dan Stoza        BufferQueue::createBufferQueue(&producer, &consumer);
1388aa0f0619ea867e8fb240cf27913d4f8ae767385Dan Stoza        mZslConsumer = new BufferItemConsumer(consumer,
139da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala            GRALLOC_USAGE_HW_CAMERA_ZSL,
1405e1f08b3917ac7900f8a11118afb7e8bf3e61c64Mathias Agopian            kZslBufferDepth);
141da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala        mZslConsumer->setFrameAvailableListener(this);
142727d172137b4f32681c098de8e2623c0b65a6406Eino-Ville Talvala        mZslConsumer->setName(String8("Camera2-ZslConsumer"));
1438aa0f0619ea867e8fb240cf27913d4f8ae767385Dan Stoza        mZslWindow = new Surface(producer);
144da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala    }
145da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala
146da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala    if (mZslStreamId != NO_STREAM) {
147da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala        // Check if stream parameters have to change
148da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala        uint32_t currentWidth, currentHeight;
149da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala        res = device->getStreamInfo(mZslStreamId,
150d46a6b9fd8b2a4f9098757384711e2cd03a91651Eino-Ville Talvala                &currentWidth, &currentHeight, 0, 0);
151da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala        if (res != OK) {
152da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala            ALOGE("%s: Camera %d: Error querying capture output stream info: "
153da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala                    "%s (%d)", __FUNCTION__,
154d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala                    mId, strerror(-res), res);
155da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala            return res;
156da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala        }
157dc2e6ddc933e40632e79a866d9ece870db1a975eEino-Ville Talvala        if (currentWidth != (uint32_t)params.fastInfo.arrayWidth ||
1586e4db898bac9499a8abe7e6b6fbf729b78f6bd68Eino-Ville Talvala                currentHeight != (uint32_t)params.fastInfo.arrayHeight) {
15947512a7da600ababdfd052b574488b9e499c22f6Eino-Ville Talvala            res = device->deleteReprocessStream(mZslReprocessStreamId);
160da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala            if (res != OK) {
161da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala                ALOGE("%s: Camera %d: Unable to delete old reprocess stream "
162da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala                        "for ZSL: %s (%d)", __FUNCTION__,
163d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala                        mId, strerror(-res), res);
164da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala                return res;
165da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala            }
166ecf17e82505fdb60d59e00b6dd59036df93de655Igor Murashkin            ALOGV("%s: Camera %d: Deleting stream %d since the buffer dimensions changed",
167d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala                __FUNCTION__, mId, mZslStreamId);
168da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala            res = device->deleteStream(mZslStreamId);
169da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala            if (res != OK) {
170da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala                ALOGE("%s: Camera %d: Unable to delete old output stream "
171da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala                        "for ZSL: %s (%d)", __FUNCTION__,
172d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala                        mId, strerror(-res), res);
173da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala                return res;
174da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala            }
175da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala            mZslStreamId = NO_STREAM;
176da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala        }
177da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala    }
178da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala
1796551e1ede59f4a3043fb141159ca67bd2c85a911Ruben Brunk    mDeleted = false;
1806551e1ede59f4a3043fb141159ca67bd2c85a911Ruben Brunk
181da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala    if (mZslStreamId == NO_STREAM) {
182da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala        // Create stream for HAL production
1836e4db898bac9499a8abe7e6b6fbf729b78f6bd68Eino-Ville Talvala        // TODO: Sort out better way to select resolution for ZSL
184e382ee28709b83264a46b09e8f766c5ef42efa35Eino-Ville Talvala        int streamType = params.quirks.useZslFormat ?
185e382ee28709b83264a46b09e8f766c5ef42efa35Eino-Ville Talvala                (int)CAMERA2_HAL_PIXEL_FORMAT_ZSL :
186e382ee28709b83264a46b09e8f766c5ef42efa35Eino-Ville Talvala                (int)HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED;
187da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala        res = device->createStream(mZslWindow,
188b97babb8c08969b55af3b6456d15f764c8873d3fYin-Chia Yeh                params.fastInfo.arrayWidth, params.fastInfo.arrayHeight, streamType,
189b97babb8c08969b55af3b6456d15f764c8873d3fYin-Chia Yeh                HAL_DATASPACE_UNKNOWN, CAMERA3_STREAM_ROTATION_0, &mZslStreamId);
190da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala        if (res != OK) {
191da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala            ALOGE("%s: Camera %d: Can't create output stream for ZSL: "
192d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala                    "%s (%d)", __FUNCTION__, mId,
193da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala                    strerror(-res), res);
194da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala            return res;
195da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala        }
196da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala        res = device->createReprocessStreamFromStream(mZslStreamId,
197da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala                &mZslReprocessStreamId);
198da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala        if (res != OK) {
199da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala            ALOGE("%s: Camera %d: Can't create reprocess stream for ZSL: "
200d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala                    "%s (%d)", __FUNCTION__, mId,
201da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala                    strerror(-res), res);
202da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala            return res;
203da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala        }
204da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala    }
2054865c526e681366481b0ab242ffa1ead57bb02ccEino-Ville Talvala    client->registerFrameListener(Camera2Client::kPreviewRequestIdStart,
2064865c526e681366481b0ab242ffa1ead57bb02ccEino-Ville Talvala            Camera2Client::kPreviewRequestIdEnd,
20725a0aef19e170d2695f64b4c48296e7914155a88Zhijun He            this,
20825a0aef19e170d2695f64b4c48296e7914155a88Zhijun He            /*sendPartials*/false);
209da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala
210da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala    return OK;
211da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala}
212da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala
213da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvalastatus_t ZslProcessor::deleteStream() {
214da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala    ATRACE_CALL();
2156551e1ede59f4a3043fb141159ca67bd2c85a911Ruben Brunk    Mutex::Autolock l(mInputMutex);
2166551e1ede59f4a3043fb141159ca67bd2c85a911Ruben Brunk    // WAR(b/15408128): do not delete stream unless client is being disconnected.
2176551e1ede59f4a3043fb141159ca67bd2c85a911Ruben Brunk    mDeleted = true;
2186551e1ede59f4a3043fb141159ca67bd2c85a911Ruben Brunk    return OK;
2196551e1ede59f4a3043fb141159ca67bd2c85a911Ruben Brunk}
2206551e1ede59f4a3043fb141159ca67bd2c85a911Ruben Brunk
2216551e1ede59f4a3043fb141159ca67bd2c85a911Ruben Brunkstatus_t ZslProcessor::disconnect() {
2226551e1ede59f4a3043fb141159ca67bd2c85a911Ruben Brunk    ATRACE_CALL();
223da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala    status_t res;
224da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala
225da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala    Mutex::Autolock l(mInputMutex);
226da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala
227da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala    if (mZslStreamId != NO_STREAM) {
228d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala        sp<CameraDeviceBase> device = mDevice.promote();
229d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala        if (device == 0) {
230d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala            ALOGE("%s: Camera %d: Device does not exist", __FUNCTION__, mId);
231d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala            return INVALID_OPERATION;
232d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala        }
233d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala
234d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala        clearZslQueueLocked();
235da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala
23647512a7da600ababdfd052b574488b9e499c22f6Eino-Ville Talvala        res = device->deleteReprocessStream(mZslReprocessStreamId);
23747512a7da600ababdfd052b574488b9e499c22f6Eino-Ville Talvala        if (res != OK) {
23847512a7da600ababdfd052b574488b9e499c22f6Eino-Ville Talvala            ALOGE("%s: Camera %d: Cannot delete ZSL reprocessing stream %d: "
239d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala                    "%s (%d)", __FUNCTION__, mId,
24047512a7da600ababdfd052b574488b9e499c22f6Eino-Ville Talvala                    mZslReprocessStreamId, strerror(-res), res);
24147512a7da600ababdfd052b574488b9e499c22f6Eino-Ville Talvala            return res;
24247512a7da600ababdfd052b574488b9e499c22f6Eino-Ville Talvala        }
24347512a7da600ababdfd052b574488b9e499c22f6Eino-Ville Talvala
244da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala        mZslReprocessStreamId = NO_STREAM;
24547512a7da600ababdfd052b574488b9e499c22f6Eino-Ville Talvala        res = device->deleteStream(mZslStreamId);
24647512a7da600ababdfd052b574488b9e499c22f6Eino-Ville Talvala        if (res != OK) {
24747512a7da600ababdfd052b574488b9e499c22f6Eino-Ville Talvala            ALOGE("%s: Camera %d: Cannot delete ZSL output stream %d: "
248d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala                    "%s (%d)", __FUNCTION__, mId,
24947512a7da600ababdfd052b574488b9e499c22f6Eino-Ville Talvala                    mZslStreamId, strerror(-res), res);
25047512a7da600ababdfd052b574488b9e499c22f6Eino-Ville Talvala            return res;
25147512a7da600ababdfd052b574488b9e499c22f6Eino-Ville Talvala        }
252cf70d3469332445dc3ffd09729da3538612b1bb2Eino-Ville Talvala
253cf70d3469332445dc3ffd09729da3538612b1bb2Eino-Ville Talvala        mZslWindow.clear();
254cf70d3469332445dc3ffd09729da3538612b1bb2Eino-Ville Talvala        mZslConsumer.clear();
255cf70d3469332445dc3ffd09729da3538612b1bb2Eino-Ville Talvala
256da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala        mZslStreamId = NO_STREAM;
257da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala    }
258da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala    return OK;
259da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala}
260da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala
261da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvalaint ZslProcessor::getStreamId() const {
262da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala    Mutex::Autolock l(mInputMutex);
263da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala    return mZslStreamId;
264da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala}
265da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala
266da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvalastatus_t ZslProcessor::pushToReprocess(int32_t requestId) {
267da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala    ALOGV("%s: Send in reprocess request with id %d",
268da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala            __FUNCTION__, requestId);
269da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala    Mutex::Autolock l(mInputMutex);
270da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala    status_t res;
271da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala    sp<Camera2Client> client = mClient.promote();
272da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala
273d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala    if (client == 0) {
274d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala        ALOGE("%s: Camera %d: Client does not exist", __FUNCTION__, mId);
275d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala        return INVALID_OPERATION;
276d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala    }
27797b38a81ac989ccba02d726011a82541f14166dfEino-Ville Talvala
27897b38a81ac989ccba02d726011a82541f14166dfEino-Ville Talvala    IF_ALOGV() {
27997b38a81ac989ccba02d726011a82541f14166dfEino-Ville Talvala        dumpZslQueue(-1);
28097b38a81ac989ccba02d726011a82541f14166dfEino-Ville Talvala    }
28197b38a81ac989ccba02d726011a82541f14166dfEino-Ville Talvala
282da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala    if (mZslQueueTail != mZslQueueHead) {
283bdde5f884eaf270ab4b806849f3122a46cd872ceEino-Ville Talvala        CameraMetadata request;
284bdde5f884eaf270ab4b806849f3122a46cd872ceEino-Ville Talvala        size_t index = mZslQueueTail;
2854d410ede659448557398c84552eb0bf50ef09cbcEino-Ville Talvala        while (index != mZslQueueHead) {
2864d410ede659448557398c84552eb0bf50ef09cbcEino-Ville Talvala            if (!mZslQueue[index].frame.isEmpty()) {
2874d410ede659448557398c84552eb0bf50ef09cbcEino-Ville Talvala                request = mZslQueue[index].frame;
2884d410ede659448557398c84552eb0bf50ef09cbcEino-Ville Talvala                break;
2894d410ede659448557398c84552eb0bf50ef09cbcEino-Ville Talvala            }
290bdde5f884eaf270ab4b806849f3122a46cd872ceEino-Ville Talvala            index = (index + 1) % kZslBufferDepth;
291bdde5f884eaf270ab4b806849f3122a46cd872ceEino-Ville Talvala        }
2924d410ede659448557398c84552eb0bf50ef09cbcEino-Ville Talvala        if (index == mZslQueueHead) {
29397b38a81ac989ccba02d726011a82541f14166dfEino-Ville Talvala            ALOGV("%s: ZSL queue has no valid frames to send yet.",
29497b38a81ac989ccba02d726011a82541f14166dfEino-Ville Talvala                  __FUNCTION__);
29597b38a81ac989ccba02d726011a82541f14166dfEino-Ville Talvala            return NOT_ENOUGH_DATA;
29697b38a81ac989ccba02d726011a82541f14166dfEino-Ville Talvala        }
29797b38a81ac989ccba02d726011a82541f14166dfEino-Ville Talvala        // Verify that the frame is reasonable for reprocessing
29897b38a81ac989ccba02d726011a82541f14166dfEino-Ville Talvala
29997b38a81ac989ccba02d726011a82541f14166dfEino-Ville Talvala        camera_metadata_entry_t entry;
30097b38a81ac989ccba02d726011a82541f14166dfEino-Ville Talvala        entry = request.find(ANDROID_CONTROL_AE_STATE);
30197b38a81ac989ccba02d726011a82541f14166dfEino-Ville Talvala        if (entry.count == 0) {
30297b38a81ac989ccba02d726011a82541f14166dfEino-Ville Talvala            ALOGE("%s: ZSL queue frame has no AE state field!",
30397b38a81ac989ccba02d726011a82541f14166dfEino-Ville Talvala                    __FUNCTION__);
304bdde5f884eaf270ab4b806849f3122a46cd872ceEino-Ville Talvala            return BAD_VALUE;
305bdde5f884eaf270ab4b806849f3122a46cd872ceEino-Ville Talvala        }
30697b38a81ac989ccba02d726011a82541f14166dfEino-Ville Talvala        if (entry.data.u8[0] != ANDROID_CONTROL_AE_STATE_CONVERGED &&
30797b38a81ac989ccba02d726011a82541f14166dfEino-Ville Talvala                entry.data.u8[0] != ANDROID_CONTROL_AE_STATE_LOCKED) {
30897b38a81ac989ccba02d726011a82541f14166dfEino-Ville Talvala            ALOGV("%s: ZSL queue frame AE state is %d, need full capture",
30997b38a81ac989ccba02d726011a82541f14166dfEino-Ville Talvala                    __FUNCTION__, entry.data.u8[0]);
31097b38a81ac989ccba02d726011a82541f14166dfEino-Ville Talvala            return NOT_ENOUGH_DATA;
31197b38a81ac989ccba02d726011a82541f14166dfEino-Ville Talvala        }
31297b38a81ac989ccba02d726011a82541f14166dfEino-Ville Talvala
313da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala        buffer_handle_t *handle =
314bdde5f884eaf270ab4b806849f3122a46cd872ceEino-Ville Talvala            &(mZslQueue[index].buffer.mGraphicBuffer->handle);
315bdde5f884eaf270ab4b806849f3122a46cd872ceEino-Ville Talvala
316da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala        uint8_t requestType = ANDROID_REQUEST_TYPE_REPROCESS;
317da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala        res = request.update(ANDROID_REQUEST_TYPE,
318da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala                &requestType, 1);
319d1d6467d3bcbc1305eeba0176a2edf04925c368eZhijun He        int32_t inputStreams[1] =
320d1d6467d3bcbc1305eeba0176a2edf04925c368eZhijun He                { mZslReprocessStreamId };
321da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala        if (res == OK) request.update(ANDROID_REQUEST_INPUT_STREAMS,
322da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala                inputStreams, 1);
323d1d6467d3bcbc1305eeba0176a2edf04925c368eZhijun He        int32_t outputStreams[1] =
324d1d6467d3bcbc1305eeba0176a2edf04925c368eZhijun He                { client->getCaptureStreamId() };
325da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala        if (res == OK) request.update(ANDROID_REQUEST_OUTPUT_STREAMS,
326da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala                outputStreams, 1);
327da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala        res = request.update(ANDROID_REQUEST_ID,
328da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala                &requestId, 1);
329da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala
330da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala        if (res != OK ) {
331da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala            ALOGE("%s: Unable to update frame to a reprocess request", __FUNCTION__);
332da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala            return INVALID_OPERATION;
333da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala        }
334da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala
3354865c526e681366481b0ab242ffa1ead57bb02ccEino-Ville Talvala        res = client->stopStream();
336c20630569431234db23b6182dd17102023dee68eAlex Ray        if (res != OK) {
337c20630569431234db23b6182dd17102023dee68eAlex Ray            ALOGE("%s: Camera %d: Unable to stop preview for ZSL capture: "
338c20630569431234db23b6182dd17102023dee68eAlex Ray                "%s (%d)",
339d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala                __FUNCTION__, mId, strerror(-res), res);
340c20630569431234db23b6182dd17102023dee68eAlex Ray            return INVALID_OPERATION;
341c20630569431234db23b6182dd17102023dee68eAlex Ray        }
342c20630569431234db23b6182dd17102023dee68eAlex Ray        // TODO: have push-and-clear be atomic
343da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala        res = client->getCameraDevice()->pushReprocessBuffer(mZslReprocessStreamId,
344da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala                handle, this);
345da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala        if (res != OK) {
346da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala            ALOGE("%s: Unable to push buffer for reprocessing: %s (%d)",
347da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala                    __FUNCTION__, strerror(-res), res);
348da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala            return res;
349da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala        }
350da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala
351ec7710898208162576c3242f5a590651ab42aa2dEino-Ville Talvala        // Update JPEG settings
352ec7710898208162576c3242f5a590651ab42aa2dEino-Ville Talvala        {
353ec7710898208162576c3242f5a590651ab42aa2dEino-Ville Talvala            SharedParameters::Lock l(client->getParameters());
354ec7710898208162576c3242f5a590651ab42aa2dEino-Ville Talvala            res = l.mParameters.updateRequestJpeg(&request);
355ec7710898208162576c3242f5a590651ab42aa2dEino-Ville Talvala            if (res != OK) {
356ec7710898208162576c3242f5a590651ab42aa2dEino-Ville Talvala                ALOGE("%s: Camera %d: Unable to update JPEG entries of ZSL "
357ec7710898208162576c3242f5a590651ab42aa2dEino-Ville Talvala                        "capture request: %s (%d)", __FUNCTION__,
358d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala                        mId,
359ec7710898208162576c3242f5a590651ab42aa2dEino-Ville Talvala                        strerror(-res), res);
360ec7710898208162576c3242f5a590651ab42aa2dEino-Ville Talvala                return res;
361ec7710898208162576c3242f5a590651ab42aa2dEino-Ville Talvala            }
362ec7710898208162576c3242f5a590651ab42aa2dEino-Ville Talvala        }
363ec7710898208162576c3242f5a590651ab42aa2dEino-Ville Talvala
364ec7710898208162576c3242f5a590651ab42aa2dEino-Ville Talvala        mLatestCapturedRequest = request;
365da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala        res = client->getCameraDevice()->capture(request);
366da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala        if (res != OK ) {
367da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala            ALOGE("%s: Unable to send ZSL reprocess request to capture: %s (%d)",
368da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala                    __FUNCTION__, strerror(-res), res);
369da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala            return res;
370da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala        }
371da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala
372da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala        mState = LOCKED;
373da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala    } else {
37497b38a81ac989ccba02d726011a82541f14166dfEino-Ville Talvala        ALOGV("%s: No ZSL buffers yet", __FUNCTION__);
37597b38a81ac989ccba02d726011a82541f14166dfEino-Ville Talvala        return NOT_ENOUGH_DATA;
376da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala    }
377da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala    return OK;
378da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala}
379da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala
380768cf093dade9085e0ad6305d9f7c16ae9ad9e26Eino-Ville Talvalastatus_t ZslProcessor::clearZslQueue() {
381768cf093dade9085e0ad6305d9f7c16ae9ad9e26Eino-Ville Talvala    Mutex::Autolock l(mInputMutex);
382768cf093dade9085e0ad6305d9f7c16ae9ad9e26Eino-Ville Talvala    // If in middle of capture, can't clear out queue
383768cf093dade9085e0ad6305d9f7c16ae9ad9e26Eino-Ville Talvala    if (mState == LOCKED) return OK;
384768cf093dade9085e0ad6305d9f7c16ae9ad9e26Eino-Ville Talvala
385768cf093dade9085e0ad6305d9f7c16ae9ad9e26Eino-Ville Talvala    return clearZslQueueLocked();
386768cf093dade9085e0ad6305d9f7c16ae9ad9e26Eino-Ville Talvala}
387768cf093dade9085e0ad6305d9f7c16ae9ad9e26Eino-Ville Talvala
388768cf093dade9085e0ad6305d9f7c16ae9ad9e26Eino-Ville Talvalastatus_t ZslProcessor::clearZslQueueLocked() {
389768cf093dade9085e0ad6305d9f7c16ae9ad9e26Eino-Ville Talvala    for (size_t i = 0; i < mZslQueue.size(); i++) {
390768cf093dade9085e0ad6305d9f7c16ae9ad9e26Eino-Ville Talvala        if (mZslQueue[i].buffer.mTimestamp != 0) {
391768cf093dade9085e0ad6305d9f7c16ae9ad9e26Eino-Ville Talvala            mZslConsumer->releaseBuffer(mZslQueue[i].buffer);
392768cf093dade9085e0ad6305d9f7c16ae9ad9e26Eino-Ville Talvala        }
393768cf093dade9085e0ad6305d9f7c16ae9ad9e26Eino-Ville Talvala        mZslQueue.replaceAt(i);
394768cf093dade9085e0ad6305d9f7c16ae9ad9e26Eino-Ville Talvala    }
395768cf093dade9085e0ad6305d9f7c16ae9ad9e26Eino-Ville Talvala    mZslQueueHead = 0;
396768cf093dade9085e0ad6305d9f7c16ae9ad9e26Eino-Ville Talvala    mZslQueueTail = 0;
397768cf093dade9085e0ad6305d9f7c16ae9ad9e26Eino-Ville Talvala    return OK;
398768cf093dade9085e0ad6305d9f7c16ae9ad9e26Eino-Ville Talvala}
399768cf093dade9085e0ad6305d9f7c16ae9ad9e26Eino-Ville Talvala
400ddf3c5025e2f6f35a4c188c19f30142c64a092c4Igor Murashkinvoid ZslProcessor::dump(int fd, const Vector<String16>& /*args*/) const {
40197b38a81ac989ccba02d726011a82541f14166dfEino-Ville Talvala    Mutex::Autolock l(mInputMutex);
402ec7710898208162576c3242f5a590651ab42aa2dEino-Ville Talvala    if (!mLatestCapturedRequest.isEmpty()) {
403ec7710898208162576c3242f5a590651ab42aa2dEino-Ville Talvala        String8 result("    Latest ZSL capture request:\n");
404ec7710898208162576c3242f5a590651ab42aa2dEino-Ville Talvala        write(fd, result.string(), result.size());
405ec7710898208162576c3242f5a590651ab42aa2dEino-Ville Talvala        mLatestCapturedRequest.dump(fd, 2, 6);
406ec7710898208162576c3242f5a590651ab42aa2dEino-Ville Talvala    } else {
407ec7710898208162576c3242f5a590651ab42aa2dEino-Ville Talvala        String8 result("    Latest ZSL capture request: none yet\n");
408ec7710898208162576c3242f5a590651ab42aa2dEino-Ville Talvala        write(fd, result.string(), result.size());
409ec7710898208162576c3242f5a590651ab42aa2dEino-Ville Talvala    }
41097b38a81ac989ccba02d726011a82541f14166dfEino-Ville Talvala    dumpZslQueue(fd);
411da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala}
412da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala
413da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvalabool ZslProcessor::threadLoop() {
414da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala    status_t res;
415da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala
416da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala    {
417da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala        Mutex::Autolock l(mInputMutex);
418da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala        while (!mZslBufferAvailable) {
419da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala            res = mZslBufferAvailableSignal.waitRelative(mInputMutex,
420da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala                    kWaitDuration);
421da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala            if (res == TIMED_OUT) return true;
422da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala        }
423da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala        mZslBufferAvailable = false;
424da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala    }
425da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala
426da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala    do {
427d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala        res = processNewZslBuffer();
428da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala    } while (res == OK);
429da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala
430da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala    return true;
431da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala}
432da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala
433d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvalastatus_t ZslProcessor::processNewZslBuffer() {
434da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala    ATRACE_CALL();
435da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala    status_t res;
436d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala    sp<BufferItemConsumer> zslConsumer;
437d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala    {
438d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala        Mutex::Autolock l(mInputMutex);
439d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala        if (mZslConsumer == 0) return OK;
440d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala        zslConsumer = mZslConsumer;
441d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala    }
442bdde5f884eaf270ab4b806849f3122a46cd872ceEino-Ville Talvala    ALOGVV("Trying to get next buffer");
443549e735c2ca22d16eea32fda418ba80da32a8558Dan Stoza    BufferItem item;
444656e86250cd68f7f362c50a4bc92a865e9deacbeAndy McFadden    res = zslConsumer->acquireBuffer(&item, 0);
445bdde5f884eaf270ab4b806849f3122a46cd872ceEino-Ville Talvala    if (res != OK) {
446bdde5f884eaf270ab4b806849f3122a46cd872ceEino-Ville Talvala        if (res != BufferItemConsumer::NO_BUFFER_AVAILABLE) {
447bdde5f884eaf270ab4b806849f3122a46cd872ceEino-Ville Talvala            ALOGE("%s: Camera %d: Error receiving ZSL image buffer: "
448bdde5f884eaf270ab4b806849f3122a46cd872ceEino-Ville Talvala                    "%s (%d)", __FUNCTION__,
449d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala                    mId, strerror(-res), res);
450bdde5f884eaf270ab4b806849f3122a46cd872ceEino-Ville Talvala        } else {
451bdde5f884eaf270ab4b806849f3122a46cd872ceEino-Ville Talvala            ALOGVV("  No buffer");
452bdde5f884eaf270ab4b806849f3122a46cd872ceEino-Ville Talvala        }
453bdde5f884eaf270ab4b806849f3122a46cd872ceEino-Ville Talvala        return res;
454bdde5f884eaf270ab4b806849f3122a46cd872ceEino-Ville Talvala    }
455bdde5f884eaf270ab4b806849f3122a46cd872ceEino-Ville Talvala
456da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala    Mutex::Autolock l(mInputMutex);
457da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala
458da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala    if (mState == LOCKED) {
459bdde5f884eaf270ab4b806849f3122a46cd872ceEino-Ville Talvala        ALOGVV("In capture, discarding new ZSL buffers");
460d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala        zslConsumer->releaseBuffer(item);
461da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala        return OK;
462da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala    }
463da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala
464da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala    ALOGVV("Got ZSL buffer: head: %d, tail: %d", mZslQueueHead, mZslQueueTail);
465da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala
466da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala    if ( (mZslQueueHead + 1) % kZslBufferDepth == mZslQueueTail) {
467bdde5f884eaf270ab4b806849f3122a46cd872ceEino-Ville Talvala        ALOGVV("Releasing oldest buffer");
468d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala        zslConsumer->releaseBuffer(mZslQueue[mZslQueueTail].buffer);
469da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala        mZslQueue.replaceAt(mZslQueueTail);
470da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala        mZslQueueTail = (mZslQueueTail + 1) % kZslBufferDepth;
471da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala    }
472da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala
473da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala    ZslPair &queueHead = mZslQueue.editItemAt(mZslQueueHead);
474da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala
475bdde5f884eaf270ab4b806849f3122a46cd872ceEino-Ville Talvala    queueHead.buffer = item;
476da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala    queueHead.frame.release();
477da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala
478da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala    mZslQueueHead = (mZslQueueHead + 1) % kZslBufferDepth;
479da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala
480e5729fac81c8a984e984fefc90afc64135817d4fColin Cross    ALOGVV("  Acquired buffer, timestamp %" PRId64, queueHead.buffer.mTimestamp);
481da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala
482da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala    findMatchesLocked();
483da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala
484da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala    return OK;
485da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala}
486da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala
487da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvalavoid ZslProcessor::findMatchesLocked() {
488bdde5f884eaf270ab4b806849f3122a46cd872ceEino-Ville Talvala    ALOGVV("Scanning");
489da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala    for (size_t i = 0; i < mZslQueue.size(); i++) {
490da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala        ZslPair &queueEntry = mZslQueue.editItemAt(i);
491da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala        nsecs_t bufferTimestamp = queueEntry.buffer.mTimestamp;
492bdde5f884eaf270ab4b806849f3122a46cd872ceEino-Ville Talvala        IF_ALOGV() {
493bdde5f884eaf270ab4b806849f3122a46cd872ceEino-Ville Talvala            camera_metadata_entry_t entry;
494bdde5f884eaf270ab4b806849f3122a46cd872ceEino-Ville Talvala            nsecs_t frameTimestamp = 0;
495bdde5f884eaf270ab4b806849f3122a46cd872ceEino-Ville Talvala            if (!queueEntry.frame.isEmpty()) {
496bdde5f884eaf270ab4b806849f3122a46cd872ceEino-Ville Talvala                entry = queueEntry.frame.find(ANDROID_SENSOR_TIMESTAMP);
497bdde5f884eaf270ab4b806849f3122a46cd872ceEino-Ville Talvala                frameTimestamp = entry.data.i64[0];
498bdde5f884eaf270ab4b806849f3122a46cd872ceEino-Ville Talvala            }
499e5729fac81c8a984e984fefc90afc64135817d4fColin Cross            ALOGVV("   %d: b: %" PRId64 "\tf: %" PRId64, i,
500bdde5f884eaf270ab4b806849f3122a46cd872ceEino-Ville Talvala                    bufferTimestamp, frameTimestamp );
501bdde5f884eaf270ab4b806849f3122a46cd872ceEino-Ville Talvala        }
502da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala        if (queueEntry.frame.isEmpty() && bufferTimestamp != 0) {
503da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala            // Have buffer, no matching frame. Look for one
504da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala            for (size_t j = 0; j < mFrameList.size(); j++) {
505da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala                bool match = false;
506da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala                CameraMetadata &frame = mFrameList.editItemAt(j);
507da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala                if (!frame.isEmpty()) {
508da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala                    camera_metadata_entry_t entry;
509da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala                    entry = frame.find(ANDROID_SENSOR_TIMESTAMP);
510da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala                    if (entry.count == 0) {
511da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala                        ALOGE("%s: Can't find timestamp in frame!",
512da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala                                __FUNCTION__);
513da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala                        continue;
514da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala                    }
515da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala                    nsecs_t frameTimestamp = entry.data.i64[0];
516da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala                    if (bufferTimestamp == frameTimestamp) {
517e5729fac81c8a984e984fefc90afc64135817d4fColin Cross                        ALOGVV("%s: Found match %" PRId64, __FUNCTION__,
518da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala                                frameTimestamp);
519da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala                        match = true;
520da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala                    } else {
521da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala                        int64_t delta = abs(bufferTimestamp - frameTimestamp);
522da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala                        if ( delta < 1000000) {
523e5729fac81c8a984e984fefc90afc64135817d4fColin Cross                            ALOGVV("%s: Found close match %" PRId64 " (delta %" PRId64 ")",
524da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala                                    __FUNCTION__, bufferTimestamp, delta);
525da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala                            match = true;
526da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala                        }
527da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala                    }
528da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala                }
529da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala                if (match) {
530da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala                    queueEntry.frame.acquire(frame);
531da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala                    break;
532da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala                }
533da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala            }
534da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala        }
535da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala    }
536da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala}
537da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala
53897b38a81ac989ccba02d726011a82541f14166dfEino-Ville Talvalavoid ZslProcessor::dumpZslQueue(int fd) const {
53997b38a81ac989ccba02d726011a82541f14166dfEino-Ville Talvala    String8 header("ZSL queue contents:");
54097b38a81ac989ccba02d726011a82541f14166dfEino-Ville Talvala    String8 indent("    ");
54197b38a81ac989ccba02d726011a82541f14166dfEino-Ville Talvala    ALOGV("%s", header.string());
54297b38a81ac989ccba02d726011a82541f14166dfEino-Ville Talvala    if (fd != -1) {
54397b38a81ac989ccba02d726011a82541f14166dfEino-Ville Talvala        header = indent + header + "\n";
54497b38a81ac989ccba02d726011a82541f14166dfEino-Ville Talvala        write(fd, header.string(), header.size());
54597b38a81ac989ccba02d726011a82541f14166dfEino-Ville Talvala    }
54697b38a81ac989ccba02d726011a82541f14166dfEino-Ville Talvala    for (size_t i = 0; i < mZslQueue.size(); i++) {
54797b38a81ac989ccba02d726011a82541f14166dfEino-Ville Talvala        const ZslPair &queueEntry = mZslQueue[i];
54897b38a81ac989ccba02d726011a82541f14166dfEino-Ville Talvala        nsecs_t bufferTimestamp = queueEntry.buffer.mTimestamp;
54997b38a81ac989ccba02d726011a82541f14166dfEino-Ville Talvala        camera_metadata_ro_entry_t entry;
55097b38a81ac989ccba02d726011a82541f14166dfEino-Ville Talvala        nsecs_t frameTimestamp = 0;
55197b38a81ac989ccba02d726011a82541f14166dfEino-Ville Talvala        int frameAeState = -1;
55297b38a81ac989ccba02d726011a82541f14166dfEino-Ville Talvala        if (!queueEntry.frame.isEmpty()) {
55397b38a81ac989ccba02d726011a82541f14166dfEino-Ville Talvala            entry = queueEntry.frame.find(ANDROID_SENSOR_TIMESTAMP);
55497b38a81ac989ccba02d726011a82541f14166dfEino-Ville Talvala            if (entry.count > 0) frameTimestamp = entry.data.i64[0];
55597b38a81ac989ccba02d726011a82541f14166dfEino-Ville Talvala            entry = queueEntry.frame.find(ANDROID_CONTROL_AE_STATE);
55697b38a81ac989ccba02d726011a82541f14166dfEino-Ville Talvala            if (entry.count > 0) frameAeState = entry.data.u8[0];
55797b38a81ac989ccba02d726011a82541f14166dfEino-Ville Talvala        }
55897b38a81ac989ccba02d726011a82541f14166dfEino-Ville Talvala        String8 result =
559e5729fac81c8a984e984fefc90afc64135817d4fColin Cross                String8::format("   %zu: b: %" PRId64 "\tf: %" PRId64 ", AE state: %d", i,
56097b38a81ac989ccba02d726011a82541f14166dfEino-Ville Talvala                        bufferTimestamp, frameTimestamp, frameAeState);
56197b38a81ac989ccba02d726011a82541f14166dfEino-Ville Talvala        ALOGV("%s", result.string());
56297b38a81ac989ccba02d726011a82541f14166dfEino-Ville Talvala        if (fd != -1) {
56397b38a81ac989ccba02d726011a82541f14166dfEino-Ville Talvala            result = indent + result + "\n";
56497b38a81ac989ccba02d726011a82541f14166dfEino-Ville Talvala            write(fd, result.string(), result.size());
56597b38a81ac989ccba02d726011a82541f14166dfEino-Ville Talvala        }
56697b38a81ac989ccba02d726011a82541f14166dfEino-Ville Talvala
56797b38a81ac989ccba02d726011a82541f14166dfEino-Ville Talvala    }
56897b38a81ac989ccba02d726011a82541f14166dfEino-Ville Talvala}
56997b38a81ac989ccba02d726011a82541f14166dfEino-Ville Talvala
570da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala}; // namespace camera2
571da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala}; // namespace android
572