ZslProcessor.cpp revision 28c9b6f298134624cb52b1af4ed8716dddb983d3
1ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang/*
2ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * Copyright (C) 2012 The Android Open Source Project
3ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang *
4ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * Licensed under the Apache License, Version 2.0 (the "License");
5ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * you may not use this file except in compliance with the License.
6ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * You may obtain a copy of the License at
7ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang *
8ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang *      http://www.apache.org/licenses/LICENSE-2.0
9ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang *
10ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * Unless required by applicable law or agreed to in writing, software
11ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * distributed under the License is distributed on an "AS IS" BASIS,
12ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * See the License for the specific language governing permissions and
14ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * limitations under the License.
15ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang */
16ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
17ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#define LOG_TAG "Camera2-ZslProcessor"
18ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#define ATRACE_TAG ATRACE_TAG_CAMERA
19ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang//#define LOG_NDEBUG 0
20ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang//#define LOG_NNDEBUG 0
21ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
22ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#ifdef LOG_NNDEBUG
23ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#define ALOGVV(...) ALOGV(__VA_ARGS__)
24ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#else
25ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#define ALOGVV(...) ((void)0)
26ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#endif
27ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
28ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include <inttypes.h>
29ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
30ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include <utils/Log.h>
31ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include <utils/Trace.h>
32ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include <gui/Surface.h>
33ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
34ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include "common/CameraDeviceBase.h"
35ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include "api1/Camera2Client.h"
36ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include "api1/client2/CaptureSequencer.h"
37ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include "api1/client2/ZslProcessor.h"
38ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
39ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangnamespace android {
40ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangnamespace camera2 {
41ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
42ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangZslProcessor::ZslProcessor(
43ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    sp<Camera2Client> client,
44ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    wp<CaptureSequencer> sequencer):
45ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        Thread(false),
46ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        mState(RUNNING),
47ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        mClient(client),
48ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        mDevice(client->getCameraDevice()),
49ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        mSequencer(sequencer),
50ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        mId(client->getCameraId()),
5191037db265ecdd914a26e056cf69207b4f50924ehkuang        mZslBufferAvailable(false),
52ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        mZslStreamId(NO_STREAM),
53ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        mZslReprocessStreamId(NO_STREAM),
54ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        mFrameListHead(0),
55ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        mZslQueueHead(0),
56ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        mZslQueueTail(0) {
57ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    mZslQueue.insertAt(0, kZslBufferDepth);
58ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    mFrameList.insertAt(0, kFrameListDepth);
59ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    sp<CaptureSequencer> captureSequencer = mSequencer.promote();
60ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    if (captureSequencer != 0) captureSequencer->setZslProcessor(this);
61ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
62ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
63ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangZslProcessor::~ZslProcessor() {
64ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    ALOGV("%s: Exit", __FUNCTION__);
65ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    deleteStream();
66ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
6791037db265ecdd914a26e056cf69207b4f50924ehkuang
68ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangvoid ZslProcessor::onFrameAvailable() {
69ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    Mutex::Autolock l(mInputMutex);
70ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    if (!mZslBufferAvailable) {
71ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        mZslBufferAvailable = true;
72ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        mZslBufferAvailableSignal.signal();
73ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    }
74ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
75ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
76ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangvoid ZslProcessor::onResultAvailable(const CaptureResult &result) {
77ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    ATRACE_CALL();
78ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    ALOGV("%s:", __FUNCTION__);
79ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    Mutex::Autolock l(mInputMutex);
80ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    camera_metadata_ro_entry_t entry;
81ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    entry = result.mMetadata.find(ANDROID_SENSOR_TIMESTAMP);
82ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    nsecs_t timestamp = entry.data.i64[0];
83ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    (void)timestamp;
84ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    ALOGVV("Got preview frame for timestamp %" PRId64, timestamp);
85ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
86ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    if (mState != RUNNING) return;
87ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
88ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    mFrameList.editItemAt(mFrameListHead) = result.mMetadata;
89ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    mFrameListHead = (mFrameListHead + 1) % kFrameListDepth;
90ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
91ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    findMatchesLocked();
92ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
93ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
94ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangvoid ZslProcessor::onBufferReleased(buffer_handle_t *handle) {
95ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    Mutex::Autolock l(mInputMutex);
96ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
97ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    // Verify that the buffer is in our queue
98ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    size_t i = 0;
9991037db265ecdd914a26e056cf69207b4f50924ehkuang    for (; i < mZslQueue.size(); i++) {
100ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        if (&(mZslQueue[i].buffer.mGraphicBuffer->handle) == handle) break;
101ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    }
102ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    if (i == mZslQueue.size()) {
103ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        ALOGW("%s: Released buffer %p not found in queue",
104ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                __FUNCTION__, handle);
105ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    }
106ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
107ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    // Erase entire ZSL queue since we've now completed the capture and preview
108ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    // is stopped.
109ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    clearZslQueueLocked();
110ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
111ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    mState = RUNNING;
112ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
113ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
114ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangstatus_t ZslProcessor::updateStream(const Parameters &params) {
115ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    ATRACE_CALL();
11691037db265ecdd914a26e056cf69207b4f50924ehkuang    ALOGV("%s: Configuring ZSL streams", __FUNCTION__);
117ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    status_t res;
118ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
119ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    Mutex::Autolock l(mInputMutex);
120ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
121ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    sp<Camera2Client> client = mClient.promote();
122ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    if (client == 0) {
123ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        ALOGE("%s: Camera %d: Client does not exist", __FUNCTION__, mId);
124ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        return INVALID_OPERATION;
125ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    }
126ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    sp<CameraDeviceBase> device = mDevice.promote();
127ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    if (device == 0) {
128ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        ALOGE("%s: Camera %d: Device does not exist", __FUNCTION__, mId);
129ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        return INVALID_OPERATION;
130ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    }
131ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
132ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    if (mZslConsumer == 0) {
133ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        // Create CPU buffer queue endpoint
134ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        sp<IGraphicBufferProducer> producer;
135ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        sp<IGraphicBufferConsumer> consumer;
13691037db265ecdd914a26e056cf69207b4f50924ehkuang        BufferQueue::createBufferQueue(&producer, &consumer);
137ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        mZslConsumer = new BufferItemConsumer(consumer,
138ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang            GRALLOC_USAGE_HW_CAMERA_ZSL,
139ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang            kZslBufferDepth);
140ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        mZslConsumer->setFrameAvailableListener(this);
141ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        mZslConsumer->setName(String8("Camera2Client::ZslConsumer"));
14291037db265ecdd914a26e056cf69207b4f50924ehkuang        mZslWindow = new Surface(producer);
14391037db265ecdd914a26e056cf69207b4f50924ehkuang    }
14491037db265ecdd914a26e056cf69207b4f50924ehkuang
14591037db265ecdd914a26e056cf69207b4f50924ehkuang    if (mZslStreamId != NO_STREAM) {
14691037db265ecdd914a26e056cf69207b4f50924ehkuang        // Check if stream parameters have to change
14791037db265ecdd914a26e056cf69207b4f50924ehkuang        uint32_t currentWidth, currentHeight;
148ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        res = device->getStreamInfo(mZslStreamId,
149ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                &currentWidth, &currentHeight, 0);
150ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        if (res != OK) {
151ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang            ALOGE("%s: Camera %d: Error querying capture output stream info: "
152ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                    "%s (%d)", __FUNCTION__,
153ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                    mId, strerror(-res), res);
154ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang            return res;
155ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        }
156ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        if (currentWidth != (uint32_t)params.fastInfo.arrayWidth ||
157ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                currentHeight != (uint32_t)params.fastInfo.arrayHeight) {
158ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang            res = device->deleteReprocessStream(mZslReprocessStreamId);
159ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang            if (res != OK) {
160ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                ALOGE("%s: Camera %d: Unable to delete old reprocess stream "
161ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                        "for ZSL: %s (%d)", __FUNCTION__,
162ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                        mId, strerror(-res), res);
163ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                return res;
164ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang            }
165ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang            ALOGV("%s: Camera %d: Deleting stream %d since the buffer dimensions changed",
166ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                __FUNCTION__, mId, mZslStreamId);
167ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang            res = device->deleteStream(mZslStreamId);
168ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang            if (res != OK) {
169ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                ALOGE("%s: Camera %d: Unable to delete old output stream "
170ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                        "for ZSL: %s (%d)", __FUNCTION__,
171ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                        mId, strerror(-res), res);
172ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                return res;
173ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang            }
174ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang            mZslStreamId = NO_STREAM;
175ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        }
176ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    }
177ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
178ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    if (mZslStreamId == NO_STREAM) {
179ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        // Create stream for HAL production
180ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        // TODO: Sort out better way to select resolution for ZSL
181        int streamType = params.quirks.useZslFormat ?
182                (int)CAMERA2_HAL_PIXEL_FORMAT_ZSL :
183                (int)HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED;
184        res = device->createStream(mZslWindow,
185                params.fastInfo.arrayWidth, params.fastInfo.arrayHeight,
186                streamType, &mZslStreamId);
187        if (res != OK) {
188            ALOGE("%s: Camera %d: Can't create output stream for ZSL: "
189                    "%s (%d)", __FUNCTION__, mId,
190                    strerror(-res), res);
191            return res;
192        }
193        res = device->createReprocessStreamFromStream(mZslStreamId,
194                &mZslReprocessStreamId);
195        if (res != OK) {
196            ALOGE("%s: Camera %d: Can't create reprocess stream for ZSL: "
197                    "%s (%d)", __FUNCTION__, mId,
198                    strerror(-res), res);
199            return res;
200        }
201    }
202    client->registerFrameListener(Camera2Client::kPreviewRequestIdStart,
203            Camera2Client::kPreviewRequestIdEnd,
204            this,
205            /*sendPartials*/false);
206
207    return OK;
208}
209
210status_t ZslProcessor::deleteStream() {
211    ATRACE_CALL();
212    status_t res;
213
214    Mutex::Autolock l(mInputMutex);
215
216    if (mZslStreamId != NO_STREAM) {
217        sp<CameraDeviceBase> device = mDevice.promote();
218        if (device == 0) {
219            ALOGE("%s: Camera %d: Device does not exist", __FUNCTION__, mId);
220            return INVALID_OPERATION;
221        }
222
223        clearZslQueueLocked();
224
225        res = device->deleteReprocessStream(mZslReprocessStreamId);
226        if (res != OK) {
227            ALOGE("%s: Camera %d: Cannot delete ZSL reprocessing stream %d: "
228                    "%s (%d)", __FUNCTION__, mId,
229                    mZslReprocessStreamId, strerror(-res), res);
230            return res;
231        }
232
233        mZslReprocessStreamId = NO_STREAM;
234        res = device->deleteStream(mZslStreamId);
235        if (res != OK) {
236            ALOGE("%s: Camera %d: Cannot delete ZSL output stream %d: "
237                    "%s (%d)", __FUNCTION__, mId,
238                    mZslStreamId, strerror(-res), res);
239            return res;
240        }
241
242        mZslWindow.clear();
243        mZslConsumer.clear();
244
245        mZslStreamId = NO_STREAM;
246    }
247    return OK;
248}
249
250int ZslProcessor::getStreamId() const {
251    Mutex::Autolock l(mInputMutex);
252    return mZslStreamId;
253}
254
255status_t ZslProcessor::pushToReprocess(int32_t requestId) {
256    ALOGV("%s: Send in reprocess request with id %d",
257            __FUNCTION__, requestId);
258    Mutex::Autolock l(mInputMutex);
259    status_t res;
260    sp<Camera2Client> client = mClient.promote();
261
262    if (client == 0) {
263        ALOGE("%s: Camera %d: Client does not exist", __FUNCTION__, mId);
264        return INVALID_OPERATION;
265    }
266
267    IF_ALOGV() {
268        dumpZslQueue(-1);
269    }
270
271    if (mZslQueueTail != mZslQueueHead) {
272        CameraMetadata request;
273        size_t index = mZslQueueTail;
274        while (index != mZslQueueHead) {
275            if (!mZslQueue[index].frame.isEmpty()) {
276                request = mZslQueue[index].frame;
277                break;
278            }
279            index = (index + 1) % kZslBufferDepth;
280        }
281        if (index == mZslQueueHead) {
282            ALOGV("%s: ZSL queue has no valid frames to send yet.",
283                  __FUNCTION__);
284            return NOT_ENOUGH_DATA;
285        }
286        // Verify that the frame is reasonable for reprocessing
287
288        camera_metadata_entry_t entry;
289        entry = request.find(ANDROID_CONTROL_AE_STATE);
290        if (entry.count == 0) {
291            ALOGE("%s: ZSL queue frame has no AE state field!",
292                    __FUNCTION__);
293            return BAD_VALUE;
294        }
295        if (entry.data.u8[0] != ANDROID_CONTROL_AE_STATE_CONVERGED &&
296                entry.data.u8[0] != ANDROID_CONTROL_AE_STATE_LOCKED) {
297            ALOGV("%s: ZSL queue frame AE state is %d, need full capture",
298                    __FUNCTION__, entry.data.u8[0]);
299            return NOT_ENOUGH_DATA;
300        }
301
302        buffer_handle_t *handle =
303            &(mZslQueue[index].buffer.mGraphicBuffer->handle);
304
305        uint8_t requestType = ANDROID_REQUEST_TYPE_REPROCESS;
306        res = request.update(ANDROID_REQUEST_TYPE,
307                &requestType, 1);
308        int32_t inputStreams[1] =
309                { mZslReprocessStreamId };
310        if (res == OK) request.update(ANDROID_REQUEST_INPUT_STREAMS,
311                inputStreams, 1);
312        int32_t outputStreams[1] =
313                { client->getCaptureStreamId() };
314        if (res == OK) request.update(ANDROID_REQUEST_OUTPUT_STREAMS,
315                outputStreams, 1);
316        res = request.update(ANDROID_REQUEST_ID,
317                &requestId, 1);
318
319        if (res != OK ) {
320            ALOGE("%s: Unable to update frame to a reprocess request", __FUNCTION__);
321            return INVALID_OPERATION;
322        }
323
324        res = client->stopStream();
325        if (res != OK) {
326            ALOGE("%s: Camera %d: Unable to stop preview for ZSL capture: "
327                "%s (%d)",
328                __FUNCTION__, mId, strerror(-res), res);
329            return INVALID_OPERATION;
330        }
331        // TODO: have push-and-clear be atomic
332        res = client->getCameraDevice()->pushReprocessBuffer(mZslReprocessStreamId,
333                handle, this);
334        if (res != OK) {
335            ALOGE("%s: Unable to push buffer for reprocessing: %s (%d)",
336                    __FUNCTION__, strerror(-res), res);
337            return res;
338        }
339
340        // Update JPEG settings
341        {
342            SharedParameters::Lock l(client->getParameters());
343            res = l.mParameters.updateRequestJpeg(&request);
344            if (res != OK) {
345                ALOGE("%s: Camera %d: Unable to update JPEG entries of ZSL "
346                        "capture request: %s (%d)", __FUNCTION__,
347                        mId,
348                        strerror(-res), res);
349                return res;
350            }
351        }
352
353        mLatestCapturedRequest = request;
354        res = client->getCameraDevice()->capture(request);
355        if (res != OK ) {
356            ALOGE("%s: Unable to send ZSL reprocess request to capture: %s (%d)",
357                    __FUNCTION__, strerror(-res), res);
358            return res;
359        }
360
361        mState = LOCKED;
362    } else {
363        ALOGV("%s: No ZSL buffers yet", __FUNCTION__);
364        return NOT_ENOUGH_DATA;
365    }
366    return OK;
367}
368
369status_t ZslProcessor::clearZslQueue() {
370    Mutex::Autolock l(mInputMutex);
371    // If in middle of capture, can't clear out queue
372    if (mState == LOCKED) return OK;
373
374    return clearZslQueueLocked();
375}
376
377status_t ZslProcessor::clearZslQueueLocked() {
378    for (size_t i = 0; i < mZslQueue.size(); i++) {
379        if (mZslQueue[i].buffer.mTimestamp != 0) {
380            mZslConsumer->releaseBuffer(mZslQueue[i].buffer);
381        }
382        mZslQueue.replaceAt(i);
383    }
384    mZslQueueHead = 0;
385    mZslQueueTail = 0;
386    return OK;
387}
388
389void ZslProcessor::dump(int fd, const Vector<String16>& /*args*/) const {
390    Mutex::Autolock l(mInputMutex);
391    if (!mLatestCapturedRequest.isEmpty()) {
392        String8 result("    Latest ZSL capture request:\n");
393        write(fd, result.string(), result.size());
394        mLatestCapturedRequest.dump(fd, 2, 6);
395    } else {
396        String8 result("    Latest ZSL capture request: none yet\n");
397        write(fd, result.string(), result.size());
398    }
399    dumpZslQueue(fd);
400}
401
402bool ZslProcessor::threadLoop() {
403    status_t res;
404
405    {
406        Mutex::Autolock l(mInputMutex);
407        while (!mZslBufferAvailable) {
408            res = mZslBufferAvailableSignal.waitRelative(mInputMutex,
409                    kWaitDuration);
410            if (res == TIMED_OUT) return true;
411        }
412        mZslBufferAvailable = false;
413    }
414
415    do {
416        res = processNewZslBuffer();
417    } while (res == OK);
418
419    return true;
420}
421
422status_t ZslProcessor::processNewZslBuffer() {
423    ATRACE_CALL();
424    status_t res;
425    sp<BufferItemConsumer> zslConsumer;
426    {
427        Mutex::Autolock l(mInputMutex);
428        if (mZslConsumer == 0) return OK;
429        zslConsumer = mZslConsumer;
430    }
431    ALOGVV("Trying to get next buffer");
432    BufferItemConsumer::BufferItem item;
433    res = zslConsumer->acquireBuffer(&item, 0);
434    if (res != OK) {
435        if (res != BufferItemConsumer::NO_BUFFER_AVAILABLE) {
436            ALOGE("%s: Camera %d: Error receiving ZSL image buffer: "
437                    "%s (%d)", __FUNCTION__,
438                    mId, strerror(-res), res);
439        } else {
440            ALOGVV("  No buffer");
441        }
442        return res;
443    }
444
445    Mutex::Autolock l(mInputMutex);
446
447    if (mState == LOCKED) {
448        ALOGVV("In capture, discarding new ZSL buffers");
449        zslConsumer->releaseBuffer(item);
450        return OK;
451    }
452
453    ALOGVV("Got ZSL buffer: head: %d, tail: %d", mZslQueueHead, mZslQueueTail);
454
455    if ( (mZslQueueHead + 1) % kZslBufferDepth == mZslQueueTail) {
456        ALOGVV("Releasing oldest buffer");
457        zslConsumer->releaseBuffer(mZslQueue[mZslQueueTail].buffer);
458        mZslQueue.replaceAt(mZslQueueTail);
459        mZslQueueTail = (mZslQueueTail + 1) % kZslBufferDepth;
460    }
461
462    ZslPair &queueHead = mZslQueue.editItemAt(mZslQueueHead);
463
464    queueHead.buffer = item;
465    queueHead.frame.release();
466
467    mZslQueueHead = (mZslQueueHead + 1) % kZslBufferDepth;
468
469    ALOGVV("  Acquired buffer, timestamp %" PRId64, queueHead.buffer.mTimestamp);
470
471    findMatchesLocked();
472
473    return OK;
474}
475
476void ZslProcessor::findMatchesLocked() {
477    ALOGVV("Scanning");
478    for (size_t i = 0; i < mZslQueue.size(); i++) {
479        ZslPair &queueEntry = mZslQueue.editItemAt(i);
480        nsecs_t bufferTimestamp = queueEntry.buffer.mTimestamp;
481        IF_ALOGV() {
482            camera_metadata_entry_t entry;
483            nsecs_t frameTimestamp = 0;
484            if (!queueEntry.frame.isEmpty()) {
485                entry = queueEntry.frame.find(ANDROID_SENSOR_TIMESTAMP);
486                frameTimestamp = entry.data.i64[0];
487            }
488            ALOGVV("   %d: b: %" PRId64 "\tf: %" PRId64, i,
489                    bufferTimestamp, frameTimestamp );
490        }
491        if (queueEntry.frame.isEmpty() && bufferTimestamp != 0) {
492            // Have buffer, no matching frame. Look for one
493            for (size_t j = 0; j < mFrameList.size(); j++) {
494                bool match = false;
495                CameraMetadata &frame = mFrameList.editItemAt(j);
496                if (!frame.isEmpty()) {
497                    camera_metadata_entry_t entry;
498                    entry = frame.find(ANDROID_SENSOR_TIMESTAMP);
499                    if (entry.count == 0) {
500                        ALOGE("%s: Can't find timestamp in frame!",
501                                __FUNCTION__);
502                        continue;
503                    }
504                    nsecs_t frameTimestamp = entry.data.i64[0];
505                    if (bufferTimestamp == frameTimestamp) {
506                        ALOGVV("%s: Found match %" PRId64, __FUNCTION__,
507                                frameTimestamp);
508                        match = true;
509                    } else {
510                        int64_t delta = abs(bufferTimestamp - frameTimestamp);
511                        if ( delta < 1000000) {
512                            ALOGVV("%s: Found close match %" PRId64 " (delta %" PRId64 ")",
513                                    __FUNCTION__, bufferTimestamp, delta);
514                            match = true;
515                        }
516                    }
517                }
518                if (match) {
519                    queueEntry.frame.acquire(frame);
520                    break;
521                }
522            }
523        }
524    }
525}
526
527void ZslProcessor::dumpZslQueue(int fd) const {
528    String8 header("ZSL queue contents:");
529    String8 indent("    ");
530    ALOGV("%s", header.string());
531    if (fd != -1) {
532        header = indent + header + "\n";
533        write(fd, header.string(), header.size());
534    }
535    for (size_t i = 0; i < mZslQueue.size(); i++) {
536        const ZslPair &queueEntry = mZslQueue[i];
537        nsecs_t bufferTimestamp = queueEntry.buffer.mTimestamp;
538        camera_metadata_ro_entry_t entry;
539        nsecs_t frameTimestamp = 0;
540        int frameAeState = -1;
541        if (!queueEntry.frame.isEmpty()) {
542            entry = queueEntry.frame.find(ANDROID_SENSOR_TIMESTAMP);
543            if (entry.count > 0) frameTimestamp = entry.data.i64[0];
544            entry = queueEntry.frame.find(ANDROID_CONTROL_AE_STATE);
545            if (entry.count > 0) frameAeState = entry.data.u8[0];
546        }
547        String8 result =
548                String8::format("   %zu: b: %" PRId64 "\tf: %" PRId64 ", AE state: %d", i,
549                        bufferTimestamp, frameTimestamp, frameAeState);
550        ALOGV("%s", result.string());
551        if (fd != -1) {
552            result = indent + result + "\n";
553            write(fd, result.string(), result.size());
554        }
555
556    }
557}
558
559}; // namespace camera2
560}; // namespace android
561