12fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin/*
22fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin * Copyright (C) 2013 The Android Open Source Project
32fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin *
42fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin * Licensed under the Apache License, Version 2.0 (the "License");
52fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin * you may not use this file except in compliance with the License.
62fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin * You may obtain a copy of the License at
72fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin *
82fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin *      http://www.apache.org/licenses/LICENSE-2.0
92fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin *
102fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin * Unless required by applicable law or agreed to in writing, software
112fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin * distributed under the License is distributed on an "AS IS" BASIS,
122fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
132fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin * See the License for the specific language governing permissions and
142fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin * limitations under the License.
152fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin */
162fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin
172fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin#define LOG_TAG "Camera2-ZslProcessor3"
182fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin#define ATRACE_TAG ATRACE_TAG_CAMERA
192fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin//#define LOG_NDEBUG 0
202fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin//#define LOG_NNDEBUG 0
212fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin
222fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin#ifdef LOG_NNDEBUG
232fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin#define ALOGVV(...) ALOGV(__VA_ARGS__)
242fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin#else
252fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin#define ALOGVV(...) ((void)0)
262fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin#endif
272fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin
28e5729fac81c8a984e984fefc90afc64135817d4fColin Cross#include <inttypes.h>
29e5729fac81c8a984e984fefc90afc64135817d4fColin Cross
302fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin#include <utils/Log.h>
312fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin#include <utils/Trace.h>
322fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin#include <gui/Surface.h>
332fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin
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/ZslProcessor3.h"
387b82efe7a376c882f8f938e1c41b8311a8cdda4aEino-Ville Talvala#include "device3/Camera3Device.h"
392fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin
402fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkinnamespace android {
412fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkinnamespace camera2 {
422fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin
432fba584544e8687b526e3388bf7160b696da1dbaIgor MurashkinZslProcessor3::ZslProcessor3(
442fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    sp<Camera2Client> client,
452fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    wp<CaptureSequencer> sequencer):
462fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        Thread(false),
476b7a2294b9e4da784cfe4b562ee1720ad606c852Yin-Chia Yeh        mLatestClearedBufferTimestamp(0),
482fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        mState(RUNNING),
492fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        mClient(client),
502fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        mSequencer(sequencer),
512fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        mId(client->getCameraId()),
522fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        mZslStreamId(NO_STREAM),
532fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        mFrameListHead(0),
542fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        mZslQueueHead(0),
55754fb0225369123ef6e369fd91c48071dcf6057cYin-Chia Yeh        mZslQueueTail(0),
56754fb0225369123ef6e369fd91c48071dcf6057cYin-Chia Yeh        mHasFocuser(false) {
57f0d962a6737eb8eec002d6804d9ffbe7bee672a0Zhijun He    // Initialize buffer queue and frame list based on pipeline max depth.
58f0d962a6737eb8eec002d6804d9ffbe7bee672a0Zhijun He    size_t pipelineMaxDepth = kDefaultMaxPipelineDepth;
59f0d962a6737eb8eec002d6804d9ffbe7bee672a0Zhijun He    if (client != 0) {
60f0d962a6737eb8eec002d6804d9ffbe7bee672a0Zhijun He        sp<Camera3Device> device =
61f0d962a6737eb8eec002d6804d9ffbe7bee672a0Zhijun He        static_cast<Camera3Device*>(client->getCameraDevice().get());
62f0d962a6737eb8eec002d6804d9ffbe7bee672a0Zhijun He        if (device != 0) {
63f0d962a6737eb8eec002d6804d9ffbe7bee672a0Zhijun He            camera_metadata_ro_entry_t entry =
64f0d962a6737eb8eec002d6804d9ffbe7bee672a0Zhijun He                device->info().find(ANDROID_REQUEST_PIPELINE_MAX_DEPTH);
65f0d962a6737eb8eec002d6804d9ffbe7bee672a0Zhijun He            if (entry.count == 1) {
66f0d962a6737eb8eec002d6804d9ffbe7bee672a0Zhijun He                pipelineMaxDepth = entry.data.u8[0];
67f0d962a6737eb8eec002d6804d9ffbe7bee672a0Zhijun He            } else {
68f0d962a6737eb8eec002d6804d9ffbe7bee672a0Zhijun He                ALOGW("%s: Unable to find the android.request.pipelineMaxDepth,"
69f0d962a6737eb8eec002d6804d9ffbe7bee672a0Zhijun He                        " use default pipeline max depth %zu", __FUNCTION__,
70f0d962a6737eb8eec002d6804d9ffbe7bee672a0Zhijun He                        kDefaultMaxPipelineDepth);
71f0d962a6737eb8eec002d6804d9ffbe7bee672a0Zhijun He            }
72754fb0225369123ef6e369fd91c48071dcf6057cYin-Chia Yeh
73754fb0225369123ef6e369fd91c48071dcf6057cYin-Chia Yeh            entry = device->info().find(ANDROID_LENS_INFO_MINIMUM_FOCUS_DISTANCE);
74754fb0225369123ef6e369fd91c48071dcf6057cYin-Chia Yeh            if (entry.count > 0 && entry.data.f[0] != 0.) {
75754fb0225369123ef6e369fd91c48071dcf6057cYin-Chia Yeh                mHasFocuser = true;
76754fb0225369123ef6e369fd91c48071dcf6057cYin-Chia Yeh            }
77f0d962a6737eb8eec002d6804d9ffbe7bee672a0Zhijun He        }
78f0d962a6737eb8eec002d6804d9ffbe7bee672a0Zhijun He    }
79f0d962a6737eb8eec002d6804d9ffbe7bee672a0Zhijun He
80f0d962a6737eb8eec002d6804d9ffbe7bee672a0Zhijun He    ALOGV("%s: Initialize buffer queue and frame list depth based on max pipeline depth (%d)",
81f0d962a6737eb8eec002d6804d9ffbe7bee672a0Zhijun He          __FUNCTION__, pipelineMaxDepth);
82690895cfe0f128ee3fc375a357ab99b0b98394b6Yin-Chia Yeh    // Need to keep buffer queue longer than metadata queue because sometimes buffer arrives
83690895cfe0f128ee3fc375a357ab99b0b98394b6Yin-Chia Yeh    // earlier than metadata which causes the buffer corresponding to oldest metadata being
84690895cfe0f128ee3fc375a357ab99b0b98394b6Yin-Chia Yeh    // removed.
85690895cfe0f128ee3fc375a357ab99b0b98394b6Yin-Chia Yeh    mFrameListDepth = pipelineMaxDepth;
86690895cfe0f128ee3fc375a357ab99b0b98394b6Yin-Chia Yeh    mBufferQueueDepth = mFrameListDepth + 1;
87690895cfe0f128ee3fc375a357ab99b0b98394b6Yin-Chia Yeh
88f0d962a6737eb8eec002d6804d9ffbe7bee672a0Zhijun He
89f0d962a6737eb8eec002d6804d9ffbe7bee672a0Zhijun He    mZslQueue.insertAt(0, mBufferQueueDepth);
90f0d962a6737eb8eec002d6804d9ffbe7bee672a0Zhijun He    mFrameList.insertAt(0, mFrameListDepth);
912fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    sp<CaptureSequencer> captureSequencer = mSequencer.promote();
922fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    if (captureSequencer != 0) captureSequencer->setZslProcessor(this);
932fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin}
942fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin
952fba584544e8687b526e3388bf7160b696da1dbaIgor MurashkinZslProcessor3::~ZslProcessor3() {
962fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    ALOGV("%s: Exit", __FUNCTION__);
972fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    deleteStream();
982fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin}
992fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin
100cb0652e5a850b2fcd919e977247e87239efaf70eJianing Weivoid ZslProcessor3::onResultAvailable(const CaptureResult &result) {
101cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei    ATRACE_CALL();
102cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei    ALOGV("%s:", __FUNCTION__);
1032fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    Mutex::Autolock l(mInputMutex);
1042fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    camera_metadata_ro_entry_t entry;
105cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei    entry = result.mMetadata.find(ANDROID_SENSOR_TIMESTAMP);
1062fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    nsecs_t timestamp = entry.data.i64[0];
107f0d962a6737eb8eec002d6804d9ffbe7bee672a0Zhijun He    if (entry.count == 0) {
108204e3295e2814052aef7e45ee9edd60128efbbd0Zhijun He        ALOGE("%s: metadata doesn't have timestamp, skip this result", __FUNCTION__);
109f0d962a6737eb8eec002d6804d9ffbe7bee672a0Zhijun He        return;
110f0d962a6737eb8eec002d6804d9ffbe7bee672a0Zhijun He    }
111f0d962a6737eb8eec002d6804d9ffbe7bee672a0Zhijun He
112f0d962a6737eb8eec002d6804d9ffbe7bee672a0Zhijun He    entry = result.mMetadata.find(ANDROID_REQUEST_FRAME_COUNT);
113f0d962a6737eb8eec002d6804d9ffbe7bee672a0Zhijun He    if (entry.count == 0) {
114204e3295e2814052aef7e45ee9edd60128efbbd0Zhijun He        ALOGE("%s: metadata doesn't have frame number, skip this result", __FUNCTION__);
115f0d962a6737eb8eec002d6804d9ffbe7bee672a0Zhijun He        return;
116f0d962a6737eb8eec002d6804d9ffbe7bee672a0Zhijun He    }
117f0d962a6737eb8eec002d6804d9ffbe7bee672a0Zhijun He    int32_t frameNumber = entry.data.i32[0];
118f0d962a6737eb8eec002d6804d9ffbe7bee672a0Zhijun He
119f0d962a6737eb8eec002d6804d9ffbe7bee672a0Zhijun He    ALOGVV("Got preview metadata for frame %d with timestamp %" PRId64, frameNumber, timestamp);
1202fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin
1212fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    if (mState != RUNNING) return;
1222fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin
1236b7a2294b9e4da784cfe4b562ee1720ad606c852Yin-Chia Yeh    // Corresponding buffer has been cleared. No need to push into mFrameList
1246b7a2294b9e4da784cfe4b562ee1720ad606c852Yin-Chia Yeh    if (timestamp <= mLatestClearedBufferTimestamp) return;
1256b7a2294b9e4da784cfe4b562ee1720ad606c852Yin-Chia Yeh
126cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei    mFrameList.editItemAt(mFrameListHead) = result.mMetadata;
127f0d962a6737eb8eec002d6804d9ffbe7bee672a0Zhijun He    mFrameListHead = (mFrameListHead + 1) % mFrameListDepth;
1282fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin}
1292fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin
1302fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkinstatus_t ZslProcessor3::updateStream(const Parameters &params) {
1312fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    ATRACE_CALL();
1322fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    ALOGV("%s: Configuring ZSL streams", __FUNCTION__);
1332fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    status_t res;
1342fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin
1352fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    Mutex::Autolock l(mInputMutex);
1362fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin
1372fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    sp<Camera2Client> client = mClient.promote();
1382fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    if (client == 0) {
1392fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        ALOGE("%s: Camera %d: Client does not exist", __FUNCTION__, mId);
1402fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        return INVALID_OPERATION;
1412fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    }
1422fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    sp<Camera3Device> device =
1432fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        static_cast<Camera3Device*>(client->getCameraDevice().get());
1442fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    if (device == 0) {
1452fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        ALOGE("%s: Camera %d: Device does not exist", __FUNCTION__, mId);
1462fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        return INVALID_OPERATION;
1472fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    }
1482fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin
1492fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    if (mZslStreamId != NO_STREAM) {
1502fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        // Check if stream parameters have to change
1512fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        uint32_t currentWidth, currentHeight;
1522fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        res = device->getStreamInfo(mZslStreamId,
153d46a6b9fd8b2a4f9098757384711e2cd03a91651Eino-Ville Talvala                &currentWidth, &currentHeight, 0, 0);
1542fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        if (res != OK) {
1552fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin            ALOGE("%s: Camera %d: Error querying capture output stream info: "
1562fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin                    "%s (%d)", __FUNCTION__,
1572fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin                    client->getCameraId(), strerror(-res), res);
1582fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin            return res;
1592fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        }
1602fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        if (currentWidth != (uint32_t)params.fastInfo.arrayWidth ||
1612fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin                currentHeight != (uint32_t)params.fastInfo.arrayHeight) {
1622fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin            ALOGV("%s: Camera %d: Deleting stream %d since the buffer "
1632fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin                  "dimensions changed",
1642fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin                __FUNCTION__, client->getCameraId(), mZslStreamId);
1652fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin            res = device->deleteStream(mZslStreamId);
1665282713a976184e41451315f1286d8075b257d58Igor Murashkin            if (res == -EBUSY) {
1675282713a976184e41451315f1286d8075b257d58Igor Murashkin                ALOGV("%s: Camera %d: Device is busy, call updateStream again "
1685282713a976184e41451315f1286d8075b257d58Igor Murashkin                      " after it becomes idle", __FUNCTION__, mId);
1695282713a976184e41451315f1286d8075b257d58Igor Murashkin                return res;
1705282713a976184e41451315f1286d8075b257d58Igor Murashkin            } else if(res != OK) {
1712fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin                ALOGE("%s: Camera %d: Unable to delete old output stream "
1722fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin                        "for ZSL: %s (%d)", __FUNCTION__,
1732fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin                        client->getCameraId(), strerror(-res), res);
1742fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin                return res;
1752fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin            }
1762fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin            mZslStreamId = NO_STREAM;
1772fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        }
1782fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    }
1792fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin
1802fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    if (mZslStreamId == NO_STREAM) {
1812fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        // Create stream for HAL production
1822fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        // TODO: Sort out better way to select resolution for ZSL
1832fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin
1842fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        // Note that format specified internally in Camera3ZslStream
1852fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        res = device->createZslStream(
1862fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin                params.fastInfo.arrayWidth, params.fastInfo.arrayHeight,
187f0d962a6737eb8eec002d6804d9ffbe7bee672a0Zhijun He                mBufferQueueDepth,
1882fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin                &mZslStreamId,
1892fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin                &mZslStream);
1902fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        if (res != OK) {
1912fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin            ALOGE("%s: Camera %d: Can't create ZSL stream: "
1922fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin                    "%s (%d)", __FUNCTION__, client->getCameraId(),
1932fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin                    strerror(-res), res);
1942fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin            return res;
1952fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        }
196f0d962a6737eb8eec002d6804d9ffbe7bee672a0Zhijun He
197f0d962a6737eb8eec002d6804d9ffbe7bee672a0Zhijun He        // Only add the camera3 buffer listener when the stream is created.
198f0d962a6737eb8eec002d6804d9ffbe7bee672a0Zhijun He        mZslStream->addBufferListener(this);
1992fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    }
200f0d962a6737eb8eec002d6804d9ffbe7bee672a0Zhijun He
2012fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    client->registerFrameListener(Camera2Client::kPreviewRequestIdStart,
2022fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin            Camera2Client::kPreviewRequestIdEnd,
20325a0aef19e170d2695f64b4c48296e7914155a88Zhijun He            this,
20425a0aef19e170d2695f64b4c48296e7914155a88Zhijun He            /*sendPartials*/false);
2052fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin
2062fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    return OK;
2072fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin}
2082fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin
2092fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkinstatus_t ZslProcessor3::deleteStream() {
2102fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    ATRACE_CALL();
2112fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    status_t res;
2122fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin
2132fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    Mutex::Autolock l(mInputMutex);
2142fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin
2152fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    if (mZslStreamId != NO_STREAM) {
2162fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        sp<Camera2Client> client = mClient.promote();
2172fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        if (client == 0) {
2182fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin            ALOGE("%s: Camera %d: Client does not exist", __FUNCTION__, mId);
2192fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin            return INVALID_OPERATION;
2202fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        }
2212fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin
2222fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        sp<Camera3Device> device =
2232fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin            reinterpret_cast<Camera3Device*>(client->getCameraDevice().get());
2242fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        if (device == 0) {
2252fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin            ALOGE("%s: Camera %d: Device does not exist", __FUNCTION__, mId);
2262fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin            return INVALID_OPERATION;
2272fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        }
2282fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin
2292fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        res = device->deleteStream(mZslStreamId);
2302fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        if (res != OK) {
2312fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin            ALOGE("%s: Camera %d: Cannot delete ZSL output stream %d: "
2322fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin                    "%s (%d)", __FUNCTION__, client->getCameraId(),
2332fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin                    mZslStreamId, strerror(-res), res);
2342fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin            return res;
2352fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        }
2362fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin
2372fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        mZslStreamId = NO_STREAM;
2382fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    }
2392fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    return OK;
2402fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin}
2412fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin
2422fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkinint ZslProcessor3::getStreamId() const {
2432fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    Mutex::Autolock l(mInputMutex);
2442fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    return mZslStreamId;
2452fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin}
2462fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin
247a1530f1b16f093a91edbbbaf7dac9f9809867817Zhijun Hestatus_t ZslProcessor3::updateRequestWithDefaultStillRequest(CameraMetadata &request) const {
248a1530f1b16f093a91edbbbaf7dac9f9809867817Zhijun He    sp<Camera2Client> client = mClient.promote();
249a1530f1b16f093a91edbbbaf7dac9f9809867817Zhijun He    if (client == 0) {
250a1530f1b16f093a91edbbbaf7dac9f9809867817Zhijun He        ALOGE("%s: Camera %d: Client does not exist", __FUNCTION__, mId);
251a1530f1b16f093a91edbbbaf7dac9f9809867817Zhijun He        return INVALID_OPERATION;
252a1530f1b16f093a91edbbbaf7dac9f9809867817Zhijun He    }
253a1530f1b16f093a91edbbbaf7dac9f9809867817Zhijun He    sp<Camera3Device> device =
254a1530f1b16f093a91edbbbaf7dac9f9809867817Zhijun He        static_cast<Camera3Device*>(client->getCameraDevice().get());
255a1530f1b16f093a91edbbbaf7dac9f9809867817Zhijun He    if (device == 0) {
256a1530f1b16f093a91edbbbaf7dac9f9809867817Zhijun He        ALOGE("%s: Camera %d: Device does not exist", __FUNCTION__, mId);
257a1530f1b16f093a91edbbbaf7dac9f9809867817Zhijun He        return INVALID_OPERATION;
258a1530f1b16f093a91edbbbaf7dac9f9809867817Zhijun He    }
259a1530f1b16f093a91edbbbaf7dac9f9809867817Zhijun He
260a1530f1b16f093a91edbbbaf7dac9f9809867817Zhijun He    CameraMetadata stillTemplate;
261a1530f1b16f093a91edbbbaf7dac9f9809867817Zhijun He    device->createDefaultRequest(CAMERA3_TEMPLATE_STILL_CAPTURE, &stillTemplate);
262a1530f1b16f093a91edbbbaf7dac9f9809867817Zhijun He
263a1530f1b16f093a91edbbbaf7dac9f9809867817Zhijun He    // Find some of the post-processing tags, and assign the value from template to the request.
264a1530f1b16f093a91edbbbaf7dac9f9809867817Zhijun He    // Only check the aberration mode and noise reduction mode for now, as they are very important
265a1530f1b16f093a91edbbbaf7dac9f9809867817Zhijun He    // for image quality.
266a1530f1b16f093a91edbbbaf7dac9f9809867817Zhijun He    uint32_t postProcessingTags[] = {
267a1530f1b16f093a91edbbbaf7dac9f9809867817Zhijun He            ANDROID_NOISE_REDUCTION_MODE,
268a1530f1b16f093a91edbbbaf7dac9f9809867817Zhijun He            ANDROID_COLOR_CORRECTION_ABERRATION_MODE,
269a1530f1b16f093a91edbbbaf7dac9f9809867817Zhijun He            ANDROID_COLOR_CORRECTION_MODE,
270a1530f1b16f093a91edbbbaf7dac9f9809867817Zhijun He            ANDROID_TONEMAP_MODE,
271a1530f1b16f093a91edbbbaf7dac9f9809867817Zhijun He            ANDROID_SHADING_MODE,
272a1530f1b16f093a91edbbbaf7dac9f9809867817Zhijun He            ANDROID_HOT_PIXEL_MODE,
273a1530f1b16f093a91edbbbaf7dac9f9809867817Zhijun He            ANDROID_EDGE_MODE
274a1530f1b16f093a91edbbbaf7dac9f9809867817Zhijun He    };
275a1530f1b16f093a91edbbbaf7dac9f9809867817Zhijun He
276a1530f1b16f093a91edbbbaf7dac9f9809867817Zhijun He    camera_metadata_entry_t entry;
277a1530f1b16f093a91edbbbaf7dac9f9809867817Zhijun He    for (size_t i = 0; i < sizeof(postProcessingTags) / sizeof(uint32_t); i++) {
278a1530f1b16f093a91edbbbaf7dac9f9809867817Zhijun He        entry = stillTemplate.find(postProcessingTags[i]);
279a1530f1b16f093a91edbbbaf7dac9f9809867817Zhijun He        if (entry.count > 0) {
280a1530f1b16f093a91edbbbaf7dac9f9809867817Zhijun He            request.update(postProcessingTags[i], entry.data.u8, 1);
281a1530f1b16f093a91edbbbaf7dac9f9809867817Zhijun He        }
282a1530f1b16f093a91edbbbaf7dac9f9809867817Zhijun He    }
283a1530f1b16f093a91edbbbaf7dac9f9809867817Zhijun He
284a1530f1b16f093a91edbbbaf7dac9f9809867817Zhijun He    return OK;
285a1530f1b16f093a91edbbbaf7dac9f9809867817Zhijun He}
286a1530f1b16f093a91edbbbaf7dac9f9809867817Zhijun He
2872fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkinstatus_t ZslProcessor3::pushToReprocess(int32_t requestId) {
2882fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    ALOGV("%s: Send in reprocess request with id %d",
2892fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin            __FUNCTION__, requestId);
2902fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    Mutex::Autolock l(mInputMutex);
2912fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    status_t res;
2922fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    sp<Camera2Client> client = mClient.promote();
2932fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin
2942fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    if (client == 0) {
2952fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        ALOGE("%s: Camera %d: Client does not exist", __FUNCTION__, mId);
2962fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        return INVALID_OPERATION;
2972fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    }
2982fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin
2992fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    IF_ALOGV() {
3002fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        dumpZslQueue(-1);
3012fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    }
3022fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin
3032fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    size_t metadataIdx;
3042fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    nsecs_t candidateTimestamp = getCandidateTimestampLocked(&metadataIdx);
3052fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin
3062fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    if (candidateTimestamp == -1) {
3072fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        ALOGE("%s: Could not find good candidate for ZSL reprocessing",
3082fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin              __FUNCTION__);
3092fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        return NOT_ENOUGH_DATA;
3102fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    }
3112fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin
3122fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    res = mZslStream->enqueueInputBufferByTimestamp(candidateTimestamp,
3132fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin                                                    /*actualTimestamp*/NULL);
3142fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin
3152fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    if (res == mZslStream->NO_BUFFER_AVAILABLE) {
3162fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        ALOGV("%s: No ZSL buffers yet", __FUNCTION__);
3172fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        return NOT_ENOUGH_DATA;
3182fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    } else if (res != OK) {
3192fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        ALOGE("%s: Unable to push buffer for reprocessing: %s (%d)",
3202fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin                __FUNCTION__, strerror(-res), res);
3212fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        return res;
3222fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    }
3232fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin
3242fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    {
3252fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        CameraMetadata request = mFrameList[metadataIdx];
3262fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin
3272fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        // Verify that the frame is reasonable for reprocessing
3282fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin
3292fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        camera_metadata_entry_t entry;
3302fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        entry = request.find(ANDROID_CONTROL_AE_STATE);
3312fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        if (entry.count == 0) {
3322fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin            ALOGE("%s: ZSL queue frame has no AE state field!",
3332fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin                    __FUNCTION__);
3342fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin            return BAD_VALUE;
3352fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        }
3362fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        if (entry.data.u8[0] != ANDROID_CONTROL_AE_STATE_CONVERGED &&
3372fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin                entry.data.u8[0] != ANDROID_CONTROL_AE_STATE_LOCKED) {
3382fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin            ALOGV("%s: ZSL queue frame AE state is %d, need full capture",
3392fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin                    __FUNCTION__, entry.data.u8[0]);
3402fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin            return NOT_ENOUGH_DATA;
3412fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        }
3422fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin
3432fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        uint8_t requestType = ANDROID_REQUEST_TYPE_REPROCESS;
3442fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        res = request.update(ANDROID_REQUEST_TYPE,
3452fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin                &requestType, 1);
3460ea8fa4ccbf9b2b179370b983f3887d3daf2381fZhijun He        if (res != OK) {
3470ea8fa4ccbf9b2b179370b983f3887d3daf2381fZhijun He            ALOGE("%s: Unable to update request type",
3480ea8fa4ccbf9b2b179370b983f3887d3daf2381fZhijun He                  __FUNCTION__);
3490ea8fa4ccbf9b2b179370b983f3887d3daf2381fZhijun He            return INVALID_OPERATION;
3500ea8fa4ccbf9b2b179370b983f3887d3daf2381fZhijun He        }
3510ea8fa4ccbf9b2b179370b983f3887d3daf2381fZhijun He
352d1d6467d3bcbc1305eeba0176a2edf04925c368eZhijun He        int32_t inputStreams[1] =
353d1d6467d3bcbc1305eeba0176a2edf04925c368eZhijun He                { mZslStreamId };
3540ea8fa4ccbf9b2b179370b983f3887d3daf2381fZhijun He        res = request.update(ANDROID_REQUEST_INPUT_STREAMS,
3552fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin                inputStreams, 1);
3560ea8fa4ccbf9b2b179370b983f3887d3daf2381fZhijun He        if (res != OK) {
3570ea8fa4ccbf9b2b179370b983f3887d3daf2381fZhijun He            ALOGE("%s: Unable to update request input streams",
3580ea8fa4ccbf9b2b179370b983f3887d3daf2381fZhijun He                  __FUNCTION__);
3590ea8fa4ccbf9b2b179370b983f3887d3daf2381fZhijun He            return INVALID_OPERATION;
3600ea8fa4ccbf9b2b179370b983f3887d3daf2381fZhijun He        }
3610ea8fa4ccbf9b2b179370b983f3887d3daf2381fZhijun He
3620ea8fa4ccbf9b2b179370b983f3887d3daf2381fZhijun He        uint8_t captureIntent =
3630ea8fa4ccbf9b2b179370b983f3887d3daf2381fZhijun He                static_cast<uint8_t>(ANDROID_CONTROL_CAPTURE_INTENT_STILL_CAPTURE);
3640ea8fa4ccbf9b2b179370b983f3887d3daf2381fZhijun He        res = request.update(ANDROID_CONTROL_CAPTURE_INTENT,
3650ea8fa4ccbf9b2b179370b983f3887d3daf2381fZhijun He                &captureIntent, 1);
3660ea8fa4ccbf9b2b179370b983f3887d3daf2381fZhijun He        if (res != OK ) {
3670ea8fa4ccbf9b2b179370b983f3887d3daf2381fZhijun He            ALOGE("%s: Unable to update request capture intent",
3680ea8fa4ccbf9b2b179370b983f3887d3daf2381fZhijun He                  __FUNCTION__);
3690ea8fa4ccbf9b2b179370b983f3887d3daf2381fZhijun He            return INVALID_OPERATION;
3700ea8fa4ccbf9b2b179370b983f3887d3daf2381fZhijun He        }
3710ea8fa4ccbf9b2b179370b983f3887d3daf2381fZhijun He
3722fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        // TODO: Shouldn't we also update the latest preview frame?
373d1d6467d3bcbc1305eeba0176a2edf04925c368eZhijun He        int32_t outputStreams[1] =
374d1d6467d3bcbc1305eeba0176a2edf04925c368eZhijun He                { client->getCaptureStreamId() };
3750ea8fa4ccbf9b2b179370b983f3887d3daf2381fZhijun He        res = request.update(ANDROID_REQUEST_OUTPUT_STREAMS,
3762fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin                outputStreams, 1);
3770ea8fa4ccbf9b2b179370b983f3887d3daf2381fZhijun He        if (res != OK) {
3780ea8fa4ccbf9b2b179370b983f3887d3daf2381fZhijun He            ALOGE("%s: Unable to update request output streams",
3790ea8fa4ccbf9b2b179370b983f3887d3daf2381fZhijun He                  __FUNCTION__);
3800ea8fa4ccbf9b2b179370b983f3887d3daf2381fZhijun He            return INVALID_OPERATION;
3810ea8fa4ccbf9b2b179370b983f3887d3daf2381fZhijun He        }
3820ea8fa4ccbf9b2b179370b983f3887d3daf2381fZhijun He
3832fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        res = request.update(ANDROID_REQUEST_ID,
3842fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin                &requestId, 1);
3852fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        if (res != OK ) {
3862fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin            ALOGE("%s: Unable to update frame to a reprocess request",
3872fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin                  __FUNCTION__);
3882fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin            return INVALID_OPERATION;
3892fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        }
3902fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin
3912fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        res = client->stopStream();
3922fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        if (res != OK) {
3932fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin            ALOGE("%s: Camera %d: Unable to stop preview for ZSL capture: "
3942fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin                "%s (%d)",
3952fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin                __FUNCTION__, client->getCameraId(), strerror(-res), res);
3962fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin            return INVALID_OPERATION;
3972fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        }
3982fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin
3992fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        // Update JPEG settings
4002fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        {
4012fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin            SharedParameters::Lock l(client->getParameters());
4022fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin            res = l.mParameters.updateRequestJpeg(&request);
4032fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin            if (res != OK) {
4042fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin                ALOGE("%s: Camera %d: Unable to update JPEG entries of ZSL "
4052fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin                        "capture request: %s (%d)", __FUNCTION__,
4062fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin                        client->getCameraId(),
4072fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin                        strerror(-res), res);
4082fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin                return res;
4092fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin            }
4102fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        }
4112fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin
412a1530f1b16f093a91edbbbaf7dac9f9809867817Zhijun He        // Update post-processing settings
413a1530f1b16f093a91edbbbaf7dac9f9809867817Zhijun He        res = updateRequestWithDefaultStillRequest(request);
414a1530f1b16f093a91edbbbaf7dac9f9809867817Zhijun He        if (res != OK) {
415a1530f1b16f093a91edbbbaf7dac9f9809867817Zhijun He            ALOGW("%s: Unable to update post-processing tags, the reprocessed image quality "
416a1530f1b16f093a91edbbbaf7dac9f9809867817Zhijun He                    "may be compromised", __FUNCTION__);
417a1530f1b16f093a91edbbbaf7dac9f9809867817Zhijun He        }
418a1530f1b16f093a91edbbbaf7dac9f9809867817Zhijun He
4192fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        mLatestCapturedRequest = request;
4202fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        res = client->getCameraDevice()->capture(request);
4212fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        if (res != OK ) {
4222fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin            ALOGE("%s: Unable to send ZSL reprocess request to capture: %s"
4232fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin                  " (%d)", __FUNCTION__, strerror(-res), res);
4242fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin            return res;
4252fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        }
4262fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin
4272fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        mState = LOCKED;
4282fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    }
4292fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin
4302fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    return OK;
4312fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin}
4322fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin
4332fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkinstatus_t ZslProcessor3::clearZslQueue() {
4342fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    Mutex::Autolock l(mInputMutex);
4352fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    // If in middle of capture, can't clear out queue
4362fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    if (mState == LOCKED) return OK;
4372fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin
4382fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    return clearZslQueueLocked();
4392fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin}
4402fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin
4412fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkinstatus_t ZslProcessor3::clearZslQueueLocked() {
44261675c0a7b5d88d5f525b1a1926fab6a7b2c7904Igor Murashkin    if (mZslStream != 0) {
443f0d962a6737eb8eec002d6804d9ffbe7bee672a0Zhijun He        // clear result metadata list first.
444f0d962a6737eb8eec002d6804d9ffbe7bee672a0Zhijun He        clearZslResultQueueLocked();
4456b7a2294b9e4da784cfe4b562ee1720ad606c852Yin-Chia Yeh        return mZslStream->clearInputRingBuffer(&mLatestClearedBufferTimestamp);
44661675c0a7b5d88d5f525b1a1926fab6a7b2c7904Igor Murashkin    }
44761675c0a7b5d88d5f525b1a1926fab6a7b2c7904Igor Murashkin    return OK;
4482fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin}
4492fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin
450f0d962a6737eb8eec002d6804d9ffbe7bee672a0Zhijun Hevoid ZslProcessor3::clearZslResultQueueLocked() {
451f0d962a6737eb8eec002d6804d9ffbe7bee672a0Zhijun He    mFrameList.clear();
452f0d962a6737eb8eec002d6804d9ffbe7bee672a0Zhijun He    mFrameListHead = 0;
453f0d962a6737eb8eec002d6804d9ffbe7bee672a0Zhijun He    mFrameList.insertAt(0, mFrameListDepth);
454f0d962a6737eb8eec002d6804d9ffbe7bee672a0Zhijun He}
455f0d962a6737eb8eec002d6804d9ffbe7bee672a0Zhijun He
4562fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkinvoid ZslProcessor3::dump(int fd, const Vector<String16>& /*args*/) const {
4572fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    Mutex::Autolock l(mInputMutex);
4582fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    if (!mLatestCapturedRequest.isEmpty()) {
4592fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        String8 result("    Latest ZSL capture request:\n");
4602fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        write(fd, result.string(), result.size());
4612fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        mLatestCapturedRequest.dump(fd, 2, 6);
4622fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    } else {
4632fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        String8 result("    Latest ZSL capture request: none yet\n");
4642fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        write(fd, result.string(), result.size());
4652fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    }
4662fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    dumpZslQueue(fd);
4672fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin}
4682fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin
4692fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkinbool ZslProcessor3::threadLoop() {
470241b52798809d8db3d369af05ace1f73f723f29bEino-Ville Talvala    // TODO: remove dependency on thread. For now, shut thread down right
471241b52798809d8db3d369af05ace1f73f723f29bEino-Ville Talvala    // away.
472241b52798809d8db3d369af05ace1f73f723f29bEino-Ville Talvala    return false;
4732fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin}
4742fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin
4752fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkinvoid ZslProcessor3::dumpZslQueue(int fd) const {
4762fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    String8 header("ZSL queue contents:");
4772fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    String8 indent("    ");
4782fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    ALOGV("%s", header.string());
4792fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    if (fd != -1) {
4802fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        header = indent + header + "\n";
4812fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        write(fd, header.string(), header.size());
4822fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    }
4832fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    for (size_t i = 0; i < mZslQueue.size(); i++) {
4842fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        const ZslPair &queueEntry = mZslQueue[i];
4852fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        nsecs_t bufferTimestamp = queueEntry.buffer.mTimestamp;
4862fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        camera_metadata_ro_entry_t entry;
4872fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        nsecs_t frameTimestamp = 0;
4882fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        int frameAeState = -1;
4892fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        if (!queueEntry.frame.isEmpty()) {
4902fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin            entry = queueEntry.frame.find(ANDROID_SENSOR_TIMESTAMP);
4912fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin            if (entry.count > 0) frameTimestamp = entry.data.i64[0];
4922fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin            entry = queueEntry.frame.find(ANDROID_CONTROL_AE_STATE);
4932fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin            if (entry.count > 0) frameAeState = entry.data.u8[0];
4942fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        }
4952fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        String8 result =
496e5729fac81c8a984e984fefc90afc64135817d4fColin Cross                String8::format("   %zu: b: %" PRId64 "\tf: %" PRId64 ", AE state: %d", i,
4972fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin                        bufferTimestamp, frameTimestamp, frameAeState);
4982fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        ALOGV("%s", result.string());
4992fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        if (fd != -1) {
5002fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin            result = indent + result + "\n";
5012fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin            write(fd, result.string(), result.size());
5022fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        }
5032fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin
5042fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    }
5052fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin}
5062fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin
507dec84fb1c687509c3125acac76e0af80e4e0afbdYin-Chia Yehbool ZslProcessor3::isFixedFocusMode(uint8_t afMode) const {
508dec84fb1c687509c3125acac76e0af80e4e0afbdYin-Chia Yeh    switch (afMode) {
509dec84fb1c687509c3125acac76e0af80e4e0afbdYin-Chia Yeh        case ANDROID_CONTROL_AF_MODE_AUTO:
510dec84fb1c687509c3125acac76e0af80e4e0afbdYin-Chia Yeh        case ANDROID_CONTROL_AF_MODE_CONTINUOUS_VIDEO:
511dec84fb1c687509c3125acac76e0af80e4e0afbdYin-Chia Yeh        case ANDROID_CONTROL_AF_MODE_CONTINUOUS_PICTURE:
512dec84fb1c687509c3125acac76e0af80e4e0afbdYin-Chia Yeh        case ANDROID_CONTROL_AF_MODE_MACRO:
513dec84fb1c687509c3125acac76e0af80e4e0afbdYin-Chia Yeh            return false;
514dec84fb1c687509c3125acac76e0af80e4e0afbdYin-Chia Yeh            break;
515dec84fb1c687509c3125acac76e0af80e4e0afbdYin-Chia Yeh        case ANDROID_CONTROL_AF_MODE_OFF:
516dec84fb1c687509c3125acac76e0af80e4e0afbdYin-Chia Yeh        case ANDROID_CONTROL_AF_MODE_EDOF:
517dec84fb1c687509c3125acac76e0af80e4e0afbdYin-Chia Yeh            return true;
518dec84fb1c687509c3125acac76e0af80e4e0afbdYin-Chia Yeh        default:
519dec84fb1c687509c3125acac76e0af80e4e0afbdYin-Chia Yeh            ALOGE("%s: unknown focus mode %d", __FUNCTION__, afMode);
520dec84fb1c687509c3125acac76e0af80e4e0afbdYin-Chia Yeh            return false;
521dec84fb1c687509c3125acac76e0af80e4e0afbdYin-Chia Yeh    }
522dec84fb1c687509c3125acac76e0af80e4e0afbdYin-Chia Yeh}
523dec84fb1c687509c3125acac76e0af80e4e0afbdYin-Chia Yeh
5242fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkinnsecs_t ZslProcessor3::getCandidateTimestampLocked(size_t* metadataIdx) const {
5252fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    /**
5262fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin     * Find the smallest timestamp we know about so far
5272fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin     * - ensure that aeState is either converged or locked
5282fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin     */
5292fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin
5302fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    size_t idx = 0;
5312fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    nsecs_t minTimestamp = -1;
5324345d5b57a93ec6d003df84f5cce2db7cccfbd86Igor Murashkin
5334345d5b57a93ec6d003df84f5cce2db7cccfbd86Igor Murashkin    size_t emptyCount = mFrameList.size();
5344345d5b57a93ec6d003df84f5cce2db7cccfbd86Igor Murashkin
5352fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    for (size_t j = 0; j < mFrameList.size(); j++) {
5362fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        const CameraMetadata &frame = mFrameList[j];
5372fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        if (!frame.isEmpty()) {
5384345d5b57a93ec6d003df84f5cce2db7cccfbd86Igor Murashkin
5394345d5b57a93ec6d003df84f5cce2db7cccfbd86Igor Murashkin            emptyCount--;
5404345d5b57a93ec6d003df84f5cce2db7cccfbd86Igor Murashkin
5412fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin            camera_metadata_ro_entry_t entry;
5422fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin            entry = frame.find(ANDROID_SENSOR_TIMESTAMP);
5432fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin            if (entry.count == 0) {
5442fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin                ALOGE("%s: Can't find timestamp in frame!",
5452fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin                        __FUNCTION__);
5462fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin                continue;
5472fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin            }
5482fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin            nsecs_t frameTimestamp = entry.data.i64[0];
549c2c874d88df1b4be52f5415de6606785691bba1fMansoor Aftab            if (minTimestamp > frameTimestamp || minTimestamp == -1) {
5502fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin
5512fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin                entry = frame.find(ANDROID_CONTROL_AE_STATE);
5524345d5b57a93ec6d003df84f5cce2db7cccfbd86Igor Murashkin
5532fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin                if (entry.count == 0) {
5544345d5b57a93ec6d003df84f5cce2db7cccfbd86Igor Murashkin                    /**
5554345d5b57a93ec6d003df84f5cce2db7cccfbd86Igor Murashkin                     * This is most likely a HAL bug. The aeState field is
5564345d5b57a93ec6d003df84f5cce2db7cccfbd86Igor Murashkin                     * mandatory, so it should always be in a metadata packet.
5574345d5b57a93ec6d003df84f5cce2db7cccfbd86Igor Murashkin                     */
5582fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin                    ALOGW("%s: ZSL queue frame has no AE state field!",
5592fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin                            __FUNCTION__);
5602fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin                    continue;
5612fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin                }
5622fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin                if (entry.data.u8[0] != ANDROID_CONTROL_AE_STATE_CONVERGED &&
5632fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin                        entry.data.u8[0] != ANDROID_CONTROL_AE_STATE_LOCKED) {
5642fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin                    ALOGVV("%s: ZSL queue frame AE state is %d, need "
5652fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin                           "full capture",  __FUNCTION__, entry.data.u8[0]);
5662fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin                    continue;
5672fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin                }
5682fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin
569dec84fb1c687509c3125acac76e0af80e4e0afbdYin-Chia Yeh                entry = frame.find(ANDROID_CONTROL_AF_MODE);
570dec84fb1c687509c3125acac76e0af80e4e0afbdYin-Chia Yeh                if (entry.count == 0) {
571dec84fb1c687509c3125acac76e0af80e4e0afbdYin-Chia Yeh                    ALOGW("%s: ZSL queue frame has no AF mode field!",
572dec84fb1c687509c3125acac76e0af80e4e0afbdYin-Chia Yeh                            __FUNCTION__);
573dec84fb1c687509c3125acac76e0af80e4e0afbdYin-Chia Yeh                    continue;
574dec84fb1c687509c3125acac76e0af80e4e0afbdYin-Chia Yeh                }
575dec84fb1c687509c3125acac76e0af80e4e0afbdYin-Chia Yeh                uint8_t afMode = entry.data.u8[0];
57643e2418e30c360cdd43052fb3471433161cc161eZhijun He                if (afMode == ANDROID_CONTROL_AF_MODE_OFF) {
57743e2418e30c360cdd43052fb3471433161cc161eZhijun He                    // Skip all the ZSL buffer for manual AF mode, as we don't really
57843e2418e30c360cdd43052fb3471433161cc161eZhijun He                    // know the af state.
57943e2418e30c360cdd43052fb3471433161cc161eZhijun He                    continue;
58043e2418e30c360cdd43052fb3471433161cc161eZhijun He                }
581dec84fb1c687509c3125acac76e0af80e4e0afbdYin-Chia Yeh
582dec84fb1c687509c3125acac76e0af80e4e0afbdYin-Chia Yeh                // Check AF state if device has focuser and focus mode isn't fixed
583dec84fb1c687509c3125acac76e0af80e4e0afbdYin-Chia Yeh                if (mHasFocuser && !isFixedFocusMode(afMode)) {
584754fb0225369123ef6e369fd91c48071dcf6057cYin-Chia Yeh                    // Make sure the candidate frame has good focus.
585754fb0225369123ef6e369fd91c48071dcf6057cYin-Chia Yeh                    entry = frame.find(ANDROID_CONTROL_AF_STATE);
586754fb0225369123ef6e369fd91c48071dcf6057cYin-Chia Yeh                    if (entry.count == 0) {
587754fb0225369123ef6e369fd91c48071dcf6057cYin-Chia Yeh                        ALOGW("%s: ZSL queue frame has no AF state field!",
588754fb0225369123ef6e369fd91c48071dcf6057cYin-Chia Yeh                                __FUNCTION__);
589754fb0225369123ef6e369fd91c48071dcf6057cYin-Chia Yeh                        continue;
590754fb0225369123ef6e369fd91c48071dcf6057cYin-Chia Yeh                    }
591754fb0225369123ef6e369fd91c48071dcf6057cYin-Chia Yeh                    uint8_t afState = entry.data.u8[0];
592754fb0225369123ef6e369fd91c48071dcf6057cYin-Chia Yeh                    if (afState != ANDROID_CONTROL_AF_STATE_PASSIVE_FOCUSED &&
593754fb0225369123ef6e369fd91c48071dcf6057cYin-Chia Yeh                            afState != ANDROID_CONTROL_AF_STATE_FOCUSED_LOCKED &&
594754fb0225369123ef6e369fd91c48071dcf6057cYin-Chia Yeh                            afState != ANDROID_CONTROL_AF_STATE_NOT_FOCUSED_LOCKED) {
5959257000c453c1a6f6bf073ff0bf3ba7ef9baf183Ruchit Sharma                        ALOGVV("%s: ZSL queue frame AF state is %d is not good for capture, skip it",
596754fb0225369123ef6e369fd91c48071dcf6057cYin-Chia Yeh                                __FUNCTION__, afState);
597754fb0225369123ef6e369fd91c48071dcf6057cYin-Chia Yeh                        continue;
598754fb0225369123ef6e369fd91c48071dcf6057cYin-Chia Yeh                    }
5997e4c0033c5d2f9d5f53f520a9b0a2fcb8023c810Zhijun He                }
6007e4c0033c5d2f9d5f53f520a9b0a2fcb8023c810Zhijun He
6012fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin                minTimestamp = frameTimestamp;
6022fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin                idx = j;
6032fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin            }
604efb0fd232388b1f726c59f2ec20eea2d3ea8465dIgor Murashkin
605e5729fac81c8a984e984fefc90afc64135817d4fColin Cross            ALOGVV("%s: Saw timestamp %" PRId64, __FUNCTION__, frameTimestamp);
6062fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        }
6072fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    }
6082fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin
6094345d5b57a93ec6d003df84f5cce2db7cccfbd86Igor Murashkin    if (emptyCount == mFrameList.size()) {
6104345d5b57a93ec6d003df84f5cce2db7cccfbd86Igor Murashkin        /**
6114345d5b57a93ec6d003df84f5cce2db7cccfbd86Igor Murashkin         * This could be mildly bad and means our ZSL was triggered before
6124345d5b57a93ec6d003df84f5cce2db7cccfbd86Igor Murashkin         * there were any frames yet received by the camera framework.
6134345d5b57a93ec6d003df84f5cce2db7cccfbd86Igor Murashkin         *
6144345d5b57a93ec6d003df84f5cce2db7cccfbd86Igor Murashkin         * This is a fairly corner case which can happen under:
6154345d5b57a93ec6d003df84f5cce2db7cccfbd86Igor Murashkin         * + a user presses the shutter button real fast when the camera starts
6164345d5b57a93ec6d003df84f5cce2db7cccfbd86Igor Murashkin         *     (startPreview followed immediately by takePicture).
6174345d5b57a93ec6d003df84f5cce2db7cccfbd86Igor Murashkin         * + burst capture case (hitting shutter button as fast possible)
6184345d5b57a93ec6d003df84f5cce2db7cccfbd86Igor Murashkin         *
6194345d5b57a93ec6d003df84f5cce2db7cccfbd86Igor Murashkin         * If this happens in steady case (preview running for a while, call
6204345d5b57a93ec6d003df84f5cce2db7cccfbd86Igor Murashkin         *     a single takePicture) then this might be a fwk bug.
6214345d5b57a93ec6d003df84f5cce2db7cccfbd86Igor Murashkin         */
6224345d5b57a93ec6d003df84f5cce2db7cccfbd86Igor Murashkin        ALOGW("%s: ZSL queue has no metadata frames", __FUNCTION__);
6234345d5b57a93ec6d003df84f5cce2db7cccfbd86Igor Murashkin    }
6244345d5b57a93ec6d003df84f5cce2db7cccfbd86Igor Murashkin
625e5729fac81c8a984e984fefc90afc64135817d4fColin Cross    ALOGV("%s: Candidate timestamp %" PRId64 " (idx %zu), empty frames: %zu",
6264345d5b57a93ec6d003df84f5cce2db7cccfbd86Igor Murashkin          __FUNCTION__, minTimestamp, idx, emptyCount);
6274345d5b57a93ec6d003df84f5cce2db7cccfbd86Igor Murashkin
6282fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    if (metadataIdx) {
6292fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        *metadataIdx = idx;
6302fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    }
6312fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin
6322fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    return minTimestamp;
6332fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin}
6342fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin
6352fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkinvoid ZslProcessor3::onBufferAcquired(const BufferInfo& /*bufferInfo*/) {
6362fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    // Intentionally left empty
6372fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    // Although theoretically we could use this to get better dump info
6382fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin}
6392fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin
6402fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkinvoid ZslProcessor3::onBufferReleased(const BufferInfo& bufferInfo) {
6412fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin
6422fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    // ignore output buffers
6432fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    if (bufferInfo.mOutput) {
6442fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        return;
6452fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    }
6462fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin
6475487fd54f344c422be089217e62098545704bb03Zhijun He    // Lock mutex only once we know this is an input buffer returned to avoid
6485487fd54f344c422be089217e62098545704bb03Zhijun He    // potential deadlock
6495487fd54f344c422be089217e62098545704bb03Zhijun He    Mutex::Autolock l(mInputMutex);
6502fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    // TODO: Verify that the buffer is in our queue by looking at timestamp
6512fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    // theoretically unnecessary unless we change the following assumptions:
6522fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    // -- only 1 buffer reprocessed at a time (which is the case now)
6532fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin
6542fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    // Erase entire ZSL queue since we've now completed the capture and preview
6552fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    // is stopped.
6562fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    //
6572fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    // We need to guarantee that if we do two back-to-back captures,
6582fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    // the second won't use a buffer that's older/the same as the first, which
6592fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    // is theoretically possible if we don't clear out the queue and the
660f0d962a6737eb8eec002d6804d9ffbe7bee672a0Zhijun He    // selection criteria is something like 'newest'. Clearing out the result
661f0d962a6737eb8eec002d6804d9ffbe7bee672a0Zhijun He    // metadata queue on a completed capture ensures we'll only use new timestamp.
662f0d962a6737eb8eec002d6804d9ffbe7bee672a0Zhijun He    // Calling clearZslQueueLocked is a guaranteed deadlock because this callback
663f0d962a6737eb8eec002d6804d9ffbe7bee672a0Zhijun He    // holds the Camera3Stream internal lock (mLock), and clearZslQueueLocked requires
664f0d962a6737eb8eec002d6804d9ffbe7bee672a0Zhijun He    // to hold the same lock.
665f0d962a6737eb8eec002d6804d9ffbe7bee672a0Zhijun He    // TODO: need figure out a way to clear the Zsl buffer queue properly. Right now
666f0d962a6737eb8eec002d6804d9ffbe7bee672a0Zhijun He    // it is safe not to do so, as back to back ZSL capture requires stop and start
667f0d962a6737eb8eec002d6804d9ffbe7bee672a0Zhijun He    // preview, which will flush ZSL queue automatically.
6682fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    ALOGV("%s: Memory optimization, clearing ZSL queue",
6692fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin          __FUNCTION__);
670f0d962a6737eb8eec002d6804d9ffbe7bee672a0Zhijun He    clearZslResultQueueLocked();
6712fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin
6722fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    // Required so we accept more ZSL requests
6732fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    mState = RUNNING;
6742fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin}
6752fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin
6762fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin}; // namespace camera2
6772fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin}; // namespace android
678