ZslProcessor3.cpp revision 5487fd54f344c422be089217e62098545704bb03
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),
472fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        mState(RUNNING),
482fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        mClient(client),
492fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        mSequencer(sequencer),
502fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        mId(client->getCameraId()),
512fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        mZslStreamId(NO_STREAM),
522fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        mFrameListHead(0),
532fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        mZslQueueHead(0),
54754fb0225369123ef6e369fd91c48071dcf6057cYin-Chia Yeh        mZslQueueTail(0),
55754fb0225369123ef6e369fd91c48071dcf6057cYin-Chia Yeh        mHasFocuser(false) {
56f0d962a6737eb8eec002d6804d9ffbe7bee672a0Zhijun He    // Initialize buffer queue and frame list based on pipeline max depth.
57f0d962a6737eb8eec002d6804d9ffbe7bee672a0Zhijun He    size_t pipelineMaxDepth = kDefaultMaxPipelineDepth;
58f0d962a6737eb8eec002d6804d9ffbe7bee672a0Zhijun He    if (client != 0) {
59f0d962a6737eb8eec002d6804d9ffbe7bee672a0Zhijun He        sp<Camera3Device> device =
60f0d962a6737eb8eec002d6804d9ffbe7bee672a0Zhijun He        static_cast<Camera3Device*>(client->getCameraDevice().get());
61f0d962a6737eb8eec002d6804d9ffbe7bee672a0Zhijun He        if (device != 0) {
62f0d962a6737eb8eec002d6804d9ffbe7bee672a0Zhijun He            camera_metadata_ro_entry_t entry =
63f0d962a6737eb8eec002d6804d9ffbe7bee672a0Zhijun He                device->info().find(ANDROID_REQUEST_PIPELINE_MAX_DEPTH);
64f0d962a6737eb8eec002d6804d9ffbe7bee672a0Zhijun He            if (entry.count == 1) {
65f0d962a6737eb8eec002d6804d9ffbe7bee672a0Zhijun He                pipelineMaxDepth = entry.data.u8[0];
66f0d962a6737eb8eec002d6804d9ffbe7bee672a0Zhijun He            } else {
67f0d962a6737eb8eec002d6804d9ffbe7bee672a0Zhijun He                ALOGW("%s: Unable to find the android.request.pipelineMaxDepth,"
68f0d962a6737eb8eec002d6804d9ffbe7bee672a0Zhijun He                        " use default pipeline max depth %zu", __FUNCTION__,
69f0d962a6737eb8eec002d6804d9ffbe7bee672a0Zhijun He                        kDefaultMaxPipelineDepth);
70f0d962a6737eb8eec002d6804d9ffbe7bee672a0Zhijun He            }
71754fb0225369123ef6e369fd91c48071dcf6057cYin-Chia Yeh
72754fb0225369123ef6e369fd91c48071dcf6057cYin-Chia Yeh            entry = device->info().find(ANDROID_LENS_INFO_MINIMUM_FOCUS_DISTANCE);
73754fb0225369123ef6e369fd91c48071dcf6057cYin-Chia Yeh            if (entry.count > 0 && entry.data.f[0] != 0.) {
74754fb0225369123ef6e369fd91c48071dcf6057cYin-Chia Yeh                mHasFocuser = true;
75754fb0225369123ef6e369fd91c48071dcf6057cYin-Chia Yeh            }
76f0d962a6737eb8eec002d6804d9ffbe7bee672a0Zhijun He        }
77f0d962a6737eb8eec002d6804d9ffbe7bee672a0Zhijun He    }
78f0d962a6737eb8eec002d6804d9ffbe7bee672a0Zhijun He
79f0d962a6737eb8eec002d6804d9ffbe7bee672a0Zhijun He    ALOGV("%s: Initialize buffer queue and frame list depth based on max pipeline depth (%d)",
80f0d962a6737eb8eec002d6804d9ffbe7bee672a0Zhijun He          __FUNCTION__, pipelineMaxDepth);
81f0d962a6737eb8eec002d6804d9ffbe7bee672a0Zhijun He    mBufferQueueDepth = pipelineMaxDepth + 1;
82f0d962a6737eb8eec002d6804d9ffbe7bee672a0Zhijun He    mFrameListDepth = pipelineMaxDepth + 1;
83f0d962a6737eb8eec002d6804d9ffbe7bee672a0Zhijun He
84f0d962a6737eb8eec002d6804d9ffbe7bee672a0Zhijun He    mZslQueue.insertAt(0, mBufferQueueDepth);
85f0d962a6737eb8eec002d6804d9ffbe7bee672a0Zhijun He    mFrameList.insertAt(0, mFrameListDepth);
862fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    sp<CaptureSequencer> captureSequencer = mSequencer.promote();
872fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    if (captureSequencer != 0) captureSequencer->setZslProcessor(this);
882fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin}
892fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin
902fba584544e8687b526e3388bf7160b696da1dbaIgor MurashkinZslProcessor3::~ZslProcessor3() {
912fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    ALOGV("%s: Exit", __FUNCTION__);
922fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    deleteStream();
932fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin}
942fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin
95cb0652e5a850b2fcd919e977247e87239efaf70eJianing Weivoid ZslProcessor3::onResultAvailable(const CaptureResult &result) {
96cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei    ATRACE_CALL();
97cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei    ALOGV("%s:", __FUNCTION__);
982fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    Mutex::Autolock l(mInputMutex);
992fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    camera_metadata_ro_entry_t entry;
100cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei    entry = result.mMetadata.find(ANDROID_SENSOR_TIMESTAMP);
1012fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    nsecs_t timestamp = entry.data.i64[0];
102f0d962a6737eb8eec002d6804d9ffbe7bee672a0Zhijun He    if (entry.count == 0) {
103204e3295e2814052aef7e45ee9edd60128efbbd0Zhijun He        ALOGE("%s: metadata doesn't have timestamp, skip this result", __FUNCTION__);
104f0d962a6737eb8eec002d6804d9ffbe7bee672a0Zhijun He        return;
105f0d962a6737eb8eec002d6804d9ffbe7bee672a0Zhijun He    }
1062fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    (void)timestamp;
107f0d962a6737eb8eec002d6804d9ffbe7bee672a0Zhijun He
108f0d962a6737eb8eec002d6804d9ffbe7bee672a0Zhijun He    entry = result.mMetadata.find(ANDROID_REQUEST_FRAME_COUNT);
109f0d962a6737eb8eec002d6804d9ffbe7bee672a0Zhijun He    if (entry.count == 0) {
110204e3295e2814052aef7e45ee9edd60128efbbd0Zhijun He        ALOGE("%s: metadata doesn't have frame number, skip this result", __FUNCTION__);
111f0d962a6737eb8eec002d6804d9ffbe7bee672a0Zhijun He        return;
112f0d962a6737eb8eec002d6804d9ffbe7bee672a0Zhijun He    }
113f0d962a6737eb8eec002d6804d9ffbe7bee672a0Zhijun He    int32_t frameNumber = entry.data.i32[0];
114f0d962a6737eb8eec002d6804d9ffbe7bee672a0Zhijun He
115f0d962a6737eb8eec002d6804d9ffbe7bee672a0Zhijun He    ALOGVV("Got preview metadata for frame %d with timestamp %" PRId64, frameNumber, timestamp);
1162fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin
1172fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    if (mState != RUNNING) return;
1182fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin
119cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei    mFrameList.editItemAt(mFrameListHead) = result.mMetadata;
120f0d962a6737eb8eec002d6804d9ffbe7bee672a0Zhijun He    mFrameListHead = (mFrameListHead + 1) % mFrameListDepth;
1212fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin}
1222fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin
1232fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkinstatus_t ZslProcessor3::updateStream(const Parameters &params) {
1242fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    ATRACE_CALL();
1252fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    ALOGV("%s: Configuring ZSL streams", __FUNCTION__);
1262fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    status_t res;
1272fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin
1282fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    Mutex::Autolock l(mInputMutex);
1292fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin
1302fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    sp<Camera2Client> client = mClient.promote();
1312fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    if (client == 0) {
1322fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        ALOGE("%s: Camera %d: Client does not exist", __FUNCTION__, mId);
1332fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        return INVALID_OPERATION;
1342fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    }
1352fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    sp<Camera3Device> device =
1362fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        static_cast<Camera3Device*>(client->getCameraDevice().get());
1372fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    if (device == 0) {
1382fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        ALOGE("%s: Camera %d: Device does not exist", __FUNCTION__, mId);
1392fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        return INVALID_OPERATION;
1402fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    }
1412fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin
1422fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    if (mZslStreamId != NO_STREAM) {
1432fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        // Check if stream parameters have to change
1442fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        uint32_t currentWidth, currentHeight;
1452fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        res = device->getStreamInfo(mZslStreamId,
1462fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin                &currentWidth, &currentHeight, 0);
1472fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        if (res != OK) {
1482fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin            ALOGE("%s: Camera %d: Error querying capture output stream info: "
1492fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin                    "%s (%d)", __FUNCTION__,
1502fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin                    client->getCameraId(), strerror(-res), res);
1512fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin            return res;
1522fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        }
1532fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        if (currentWidth != (uint32_t)params.fastInfo.arrayWidth ||
1542fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin                currentHeight != (uint32_t)params.fastInfo.arrayHeight) {
1552fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin            ALOGV("%s: Camera %d: Deleting stream %d since the buffer "
1562fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin                  "dimensions changed",
1572fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin                __FUNCTION__, client->getCameraId(), mZslStreamId);
1582fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin            res = device->deleteStream(mZslStreamId);
1595282713a976184e41451315f1286d8075b257d58Igor Murashkin            if (res == -EBUSY) {
1605282713a976184e41451315f1286d8075b257d58Igor Murashkin                ALOGV("%s: Camera %d: Device is busy, call updateStream again "
1615282713a976184e41451315f1286d8075b257d58Igor Murashkin                      " after it becomes idle", __FUNCTION__, mId);
1625282713a976184e41451315f1286d8075b257d58Igor Murashkin                return res;
1635282713a976184e41451315f1286d8075b257d58Igor Murashkin            } else if(res != OK) {
1642fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin                ALOGE("%s: Camera %d: Unable to delete old output stream "
1652fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin                        "for ZSL: %s (%d)", __FUNCTION__,
1662fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin                        client->getCameraId(), strerror(-res), res);
1672fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin                return res;
1682fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin            }
1692fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin            mZslStreamId = NO_STREAM;
1702fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        }
1712fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    }
1722fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin
1732fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    if (mZslStreamId == NO_STREAM) {
1742fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        // Create stream for HAL production
1752fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        // TODO: Sort out better way to select resolution for ZSL
1762fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin
1772fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        // Note that format specified internally in Camera3ZslStream
1782fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        res = device->createZslStream(
1792fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin                params.fastInfo.arrayWidth, params.fastInfo.arrayHeight,
180f0d962a6737eb8eec002d6804d9ffbe7bee672a0Zhijun He                mBufferQueueDepth,
1812fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin                &mZslStreamId,
1822fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin                &mZslStream);
1832fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        if (res != OK) {
1842fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin            ALOGE("%s: Camera %d: Can't create ZSL stream: "
1852fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin                    "%s (%d)", __FUNCTION__, client->getCameraId(),
1862fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin                    strerror(-res), res);
1872fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin            return res;
1882fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        }
189f0d962a6737eb8eec002d6804d9ffbe7bee672a0Zhijun He
190f0d962a6737eb8eec002d6804d9ffbe7bee672a0Zhijun He        // Only add the camera3 buffer listener when the stream is created.
191f0d962a6737eb8eec002d6804d9ffbe7bee672a0Zhijun He        mZslStream->addBufferListener(this);
1922fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    }
193f0d962a6737eb8eec002d6804d9ffbe7bee672a0Zhijun He
1942fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    client->registerFrameListener(Camera2Client::kPreviewRequestIdStart,
1952fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin            Camera2Client::kPreviewRequestIdEnd,
19625a0aef19e170d2695f64b4c48296e7914155a88Zhijun He            this,
19725a0aef19e170d2695f64b4c48296e7914155a88Zhijun He            /*sendPartials*/false);
1982fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin
1992fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    return OK;
2002fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin}
2012fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin
2022fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkinstatus_t ZslProcessor3::deleteStream() {
2032fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    ATRACE_CALL();
2042fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    status_t res;
2052fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin
2062fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    Mutex::Autolock l(mInputMutex);
2072fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin
2082fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    if (mZslStreamId != NO_STREAM) {
2092fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        sp<Camera2Client> client = mClient.promote();
2102fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        if (client == 0) {
2112fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin            ALOGE("%s: Camera %d: Client does not exist", __FUNCTION__, mId);
2122fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin            return INVALID_OPERATION;
2132fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        }
2142fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin
2152fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        sp<Camera3Device> device =
2162fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin            reinterpret_cast<Camera3Device*>(client->getCameraDevice().get());
2172fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        if (device == 0) {
2182fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin            ALOGE("%s: Camera %d: Device does not exist", __FUNCTION__, mId);
2192fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin            return INVALID_OPERATION;
2202fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        }
2212fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin
2222fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        res = device->deleteStream(mZslStreamId);
2232fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        if (res != OK) {
2242fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin            ALOGE("%s: Camera %d: Cannot delete ZSL output stream %d: "
2252fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin                    "%s (%d)", __FUNCTION__, client->getCameraId(),
2262fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin                    mZslStreamId, strerror(-res), res);
2272fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin            return res;
2282fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        }
2292fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin
2302fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        mZslStreamId = NO_STREAM;
2312fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    }
2322fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    return OK;
2332fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin}
2342fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin
2352fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkinint ZslProcessor3::getStreamId() const {
2362fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    Mutex::Autolock l(mInputMutex);
2372fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    return mZslStreamId;
2382fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin}
2392fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin
2402fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkinstatus_t ZslProcessor3::pushToReprocess(int32_t requestId) {
2412fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    ALOGV("%s: Send in reprocess request with id %d",
2422fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin            __FUNCTION__, requestId);
2432fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    Mutex::Autolock l(mInputMutex);
2442fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    status_t res;
2452fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    sp<Camera2Client> client = mClient.promote();
2462fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin
2472fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    if (client == 0) {
2482fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        ALOGE("%s: Camera %d: Client does not exist", __FUNCTION__, mId);
2492fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        return INVALID_OPERATION;
2502fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    }
2512fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin
2522fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    IF_ALOGV() {
2532fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        dumpZslQueue(-1);
2542fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    }
2552fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin
2562fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    size_t metadataIdx;
2572fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    nsecs_t candidateTimestamp = getCandidateTimestampLocked(&metadataIdx);
2582fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin
2592fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    if (candidateTimestamp == -1) {
2602fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        ALOGE("%s: Could not find good candidate for ZSL reprocessing",
2612fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin              __FUNCTION__);
2622fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        return NOT_ENOUGH_DATA;
2632fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    }
2642fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin
2652fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    res = mZslStream->enqueueInputBufferByTimestamp(candidateTimestamp,
2662fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin                                                    /*actualTimestamp*/NULL);
2672fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin
2682fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    if (res == mZslStream->NO_BUFFER_AVAILABLE) {
2692fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        ALOGV("%s: No ZSL buffers yet", __FUNCTION__);
2702fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        return NOT_ENOUGH_DATA;
2712fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    } else if (res != OK) {
2722fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        ALOGE("%s: Unable to push buffer for reprocessing: %s (%d)",
2732fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin                __FUNCTION__, strerror(-res), res);
2742fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        return res;
2752fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    }
2762fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin
2772fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    {
2782fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        CameraMetadata request = mFrameList[metadataIdx];
2792fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin
2802fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        // Verify that the frame is reasonable for reprocessing
2812fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin
2822fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        camera_metadata_entry_t entry;
2832fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        entry = request.find(ANDROID_CONTROL_AE_STATE);
2842fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        if (entry.count == 0) {
2852fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin            ALOGE("%s: ZSL queue frame has no AE state field!",
2862fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin                    __FUNCTION__);
2872fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin            return BAD_VALUE;
2882fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        }
2892fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        if (entry.data.u8[0] != ANDROID_CONTROL_AE_STATE_CONVERGED &&
2902fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin                entry.data.u8[0] != ANDROID_CONTROL_AE_STATE_LOCKED) {
2912fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin            ALOGV("%s: ZSL queue frame AE state is %d, need full capture",
2922fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin                    __FUNCTION__, entry.data.u8[0]);
2932fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin            return NOT_ENOUGH_DATA;
2942fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        }
2952fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin
2962fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        uint8_t requestType = ANDROID_REQUEST_TYPE_REPROCESS;
2972fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        res = request.update(ANDROID_REQUEST_TYPE,
2982fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin                &requestType, 1);
2990ea8fa4ccbf9b2b179370b983f3887d3daf2381fZhijun He        if (res != OK) {
3000ea8fa4ccbf9b2b179370b983f3887d3daf2381fZhijun He            ALOGE("%s: Unable to update request type",
3010ea8fa4ccbf9b2b179370b983f3887d3daf2381fZhijun He                  __FUNCTION__);
3020ea8fa4ccbf9b2b179370b983f3887d3daf2381fZhijun He            return INVALID_OPERATION;
3030ea8fa4ccbf9b2b179370b983f3887d3daf2381fZhijun He        }
3040ea8fa4ccbf9b2b179370b983f3887d3daf2381fZhijun He
305d1d6467d3bcbc1305eeba0176a2edf04925c368eZhijun He        int32_t inputStreams[1] =
306d1d6467d3bcbc1305eeba0176a2edf04925c368eZhijun He                { mZslStreamId };
3070ea8fa4ccbf9b2b179370b983f3887d3daf2381fZhijun He        res = request.update(ANDROID_REQUEST_INPUT_STREAMS,
3082fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin                inputStreams, 1);
3090ea8fa4ccbf9b2b179370b983f3887d3daf2381fZhijun He        if (res != OK) {
3100ea8fa4ccbf9b2b179370b983f3887d3daf2381fZhijun He            ALOGE("%s: Unable to update request input streams",
3110ea8fa4ccbf9b2b179370b983f3887d3daf2381fZhijun He                  __FUNCTION__);
3120ea8fa4ccbf9b2b179370b983f3887d3daf2381fZhijun He            return INVALID_OPERATION;
3130ea8fa4ccbf9b2b179370b983f3887d3daf2381fZhijun He        }
3140ea8fa4ccbf9b2b179370b983f3887d3daf2381fZhijun He
3150ea8fa4ccbf9b2b179370b983f3887d3daf2381fZhijun He        uint8_t captureIntent =
3160ea8fa4ccbf9b2b179370b983f3887d3daf2381fZhijun He                static_cast<uint8_t>(ANDROID_CONTROL_CAPTURE_INTENT_STILL_CAPTURE);
3170ea8fa4ccbf9b2b179370b983f3887d3daf2381fZhijun He        res = request.update(ANDROID_CONTROL_CAPTURE_INTENT,
3180ea8fa4ccbf9b2b179370b983f3887d3daf2381fZhijun He                &captureIntent, 1);
3190ea8fa4ccbf9b2b179370b983f3887d3daf2381fZhijun He        if (res != OK ) {
3200ea8fa4ccbf9b2b179370b983f3887d3daf2381fZhijun He            ALOGE("%s: Unable to update request capture intent",
3210ea8fa4ccbf9b2b179370b983f3887d3daf2381fZhijun He                  __FUNCTION__);
3220ea8fa4ccbf9b2b179370b983f3887d3daf2381fZhijun He            return INVALID_OPERATION;
3230ea8fa4ccbf9b2b179370b983f3887d3daf2381fZhijun He        }
3240ea8fa4ccbf9b2b179370b983f3887d3daf2381fZhijun He
3252fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        // TODO: Shouldn't we also update the latest preview frame?
326d1d6467d3bcbc1305eeba0176a2edf04925c368eZhijun He        int32_t outputStreams[1] =
327d1d6467d3bcbc1305eeba0176a2edf04925c368eZhijun He                { client->getCaptureStreamId() };
3280ea8fa4ccbf9b2b179370b983f3887d3daf2381fZhijun He        res = request.update(ANDROID_REQUEST_OUTPUT_STREAMS,
3292fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin                outputStreams, 1);
3300ea8fa4ccbf9b2b179370b983f3887d3daf2381fZhijun He        if (res != OK) {
3310ea8fa4ccbf9b2b179370b983f3887d3daf2381fZhijun He            ALOGE("%s: Unable to update request output streams",
3320ea8fa4ccbf9b2b179370b983f3887d3daf2381fZhijun He                  __FUNCTION__);
3330ea8fa4ccbf9b2b179370b983f3887d3daf2381fZhijun He            return INVALID_OPERATION;
3340ea8fa4ccbf9b2b179370b983f3887d3daf2381fZhijun He        }
3350ea8fa4ccbf9b2b179370b983f3887d3daf2381fZhijun He
3362fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        res = request.update(ANDROID_REQUEST_ID,
3372fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin                &requestId, 1);
3382fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        if (res != OK ) {
3392fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin            ALOGE("%s: Unable to update frame to a reprocess request",
3402fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin                  __FUNCTION__);
3412fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin            return INVALID_OPERATION;
3422fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        }
3432fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin
3442fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        res = client->stopStream();
3452fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        if (res != OK) {
3462fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin            ALOGE("%s: Camera %d: Unable to stop preview for ZSL capture: "
3472fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin                "%s (%d)",
3482fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin                __FUNCTION__, client->getCameraId(), strerror(-res), res);
3492fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin            return INVALID_OPERATION;
3502fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        }
3512fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin
3522fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        // Update JPEG settings
3532fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        {
3542fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin            SharedParameters::Lock l(client->getParameters());
3552fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin            res = l.mParameters.updateRequestJpeg(&request);
3562fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin            if (res != OK) {
3572fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin                ALOGE("%s: Camera %d: Unable to update JPEG entries of ZSL "
3582fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin                        "capture request: %s (%d)", __FUNCTION__,
3592fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin                        client->getCameraId(),
3602fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin                        strerror(-res), res);
3612fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin                return res;
3622fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin            }
3632fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        }
3642fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin
3652fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        mLatestCapturedRequest = request;
3662fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        res = client->getCameraDevice()->capture(request);
3672fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        if (res != OK ) {
3682fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin            ALOGE("%s: Unable to send ZSL reprocess request to capture: %s"
3692fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin                  " (%d)", __FUNCTION__, strerror(-res), res);
3702fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin            return res;
3712fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        }
3722fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin
3732fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        mState = LOCKED;
3742fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    }
3752fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin
3762fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    return OK;
3772fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin}
3782fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin
3792fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkinstatus_t ZslProcessor3::clearZslQueue() {
3802fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    Mutex::Autolock l(mInputMutex);
3812fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    // If in middle of capture, can't clear out queue
3822fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    if (mState == LOCKED) return OK;
3832fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin
3842fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    return clearZslQueueLocked();
3852fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin}
3862fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin
3872fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkinstatus_t ZslProcessor3::clearZslQueueLocked() {
38861675c0a7b5d88d5f525b1a1926fab6a7b2c7904Igor Murashkin    if (mZslStream != 0) {
389f0d962a6737eb8eec002d6804d9ffbe7bee672a0Zhijun He        // clear result metadata list first.
390f0d962a6737eb8eec002d6804d9ffbe7bee672a0Zhijun He        clearZslResultQueueLocked();
39161675c0a7b5d88d5f525b1a1926fab6a7b2c7904Igor Murashkin        return mZslStream->clearInputRingBuffer();
39261675c0a7b5d88d5f525b1a1926fab6a7b2c7904Igor Murashkin    }
39361675c0a7b5d88d5f525b1a1926fab6a7b2c7904Igor Murashkin    return OK;
3942fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin}
3952fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin
396f0d962a6737eb8eec002d6804d9ffbe7bee672a0Zhijun Hevoid ZslProcessor3::clearZslResultQueueLocked() {
397f0d962a6737eb8eec002d6804d9ffbe7bee672a0Zhijun He    mFrameList.clear();
398f0d962a6737eb8eec002d6804d9ffbe7bee672a0Zhijun He    mFrameListHead = 0;
399f0d962a6737eb8eec002d6804d9ffbe7bee672a0Zhijun He    mFrameList.insertAt(0, mFrameListDepth);
400f0d962a6737eb8eec002d6804d9ffbe7bee672a0Zhijun He}
401f0d962a6737eb8eec002d6804d9ffbe7bee672a0Zhijun He
4022fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkinvoid ZslProcessor3::dump(int fd, const Vector<String16>& /*args*/) const {
4032fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    Mutex::Autolock l(mInputMutex);
4042fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    if (!mLatestCapturedRequest.isEmpty()) {
4052fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        String8 result("    Latest ZSL capture request:\n");
4062fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        write(fd, result.string(), result.size());
4072fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        mLatestCapturedRequest.dump(fd, 2, 6);
4082fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    } else {
4092fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        String8 result("    Latest ZSL capture request: none yet\n");
4102fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        write(fd, result.string(), result.size());
4112fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    }
4122fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    dumpZslQueue(fd);
4132fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin}
4142fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin
4152fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkinbool ZslProcessor3::threadLoop() {
416241b52798809d8db3d369af05ace1f73f723f29bEino-Ville Talvala    // TODO: remove dependency on thread. For now, shut thread down right
417241b52798809d8db3d369af05ace1f73f723f29bEino-Ville Talvala    // away.
418241b52798809d8db3d369af05ace1f73f723f29bEino-Ville Talvala    return false;
4192fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin}
4202fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin
4212fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkinvoid ZslProcessor3::dumpZslQueue(int fd) const {
4222fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    String8 header("ZSL queue contents:");
4232fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    String8 indent("    ");
4242fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    ALOGV("%s", header.string());
4252fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    if (fd != -1) {
4262fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        header = indent + header + "\n";
4272fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        write(fd, header.string(), header.size());
4282fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    }
4292fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    for (size_t i = 0; i < mZslQueue.size(); i++) {
4302fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        const ZslPair &queueEntry = mZslQueue[i];
4312fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        nsecs_t bufferTimestamp = queueEntry.buffer.mTimestamp;
4322fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        camera_metadata_ro_entry_t entry;
4332fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        nsecs_t frameTimestamp = 0;
4342fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        int frameAeState = -1;
4352fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        if (!queueEntry.frame.isEmpty()) {
4362fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin            entry = queueEntry.frame.find(ANDROID_SENSOR_TIMESTAMP);
4372fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin            if (entry.count > 0) frameTimestamp = entry.data.i64[0];
4382fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin            entry = queueEntry.frame.find(ANDROID_CONTROL_AE_STATE);
4392fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin            if (entry.count > 0) frameAeState = entry.data.u8[0];
4402fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        }
4412fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        String8 result =
442e5729fac81c8a984e984fefc90afc64135817d4fColin Cross                String8::format("   %zu: b: %" PRId64 "\tf: %" PRId64 ", AE state: %d", i,
4432fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin                        bufferTimestamp, frameTimestamp, frameAeState);
4442fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        ALOGV("%s", result.string());
4452fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        if (fd != -1) {
4462fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin            result = indent + result + "\n";
4472fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin            write(fd, result.string(), result.size());
4482fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        }
4492fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin
4502fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    }
4512fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin}
4522fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin
4532fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkinnsecs_t ZslProcessor3::getCandidateTimestampLocked(size_t* metadataIdx) const {
4542fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    /**
4552fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin     * Find the smallest timestamp we know about so far
4562fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin     * - ensure that aeState is either converged or locked
4572fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin     */
4582fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin
4592fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    size_t idx = 0;
4602fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    nsecs_t minTimestamp = -1;
4614345d5b57a93ec6d003df84f5cce2db7cccfbd86Igor Murashkin
4624345d5b57a93ec6d003df84f5cce2db7cccfbd86Igor Murashkin    size_t emptyCount = mFrameList.size();
4634345d5b57a93ec6d003df84f5cce2db7cccfbd86Igor Murashkin
4642fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    for (size_t j = 0; j < mFrameList.size(); j++) {
4652fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        const CameraMetadata &frame = mFrameList[j];
4662fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        if (!frame.isEmpty()) {
4674345d5b57a93ec6d003df84f5cce2db7cccfbd86Igor Murashkin
4684345d5b57a93ec6d003df84f5cce2db7cccfbd86Igor Murashkin            emptyCount--;
4694345d5b57a93ec6d003df84f5cce2db7cccfbd86Igor Murashkin
4702fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin            camera_metadata_ro_entry_t entry;
4712fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin            entry = frame.find(ANDROID_SENSOR_TIMESTAMP);
4722fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin            if (entry.count == 0) {
4732fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin                ALOGE("%s: Can't find timestamp in frame!",
4742fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin                        __FUNCTION__);
4752fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin                continue;
4762fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin            }
4772fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin            nsecs_t frameTimestamp = entry.data.i64[0];
478c2c874d88df1b4be52f5415de6606785691bba1fMansoor Aftab            if (minTimestamp > frameTimestamp || minTimestamp == -1) {
4792fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin
4802fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin                entry = frame.find(ANDROID_CONTROL_AE_STATE);
4814345d5b57a93ec6d003df84f5cce2db7cccfbd86Igor Murashkin
4822fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin                if (entry.count == 0) {
4834345d5b57a93ec6d003df84f5cce2db7cccfbd86Igor Murashkin                    /**
4844345d5b57a93ec6d003df84f5cce2db7cccfbd86Igor Murashkin                     * This is most likely a HAL bug. The aeState field is
4854345d5b57a93ec6d003df84f5cce2db7cccfbd86Igor Murashkin                     * mandatory, so it should always be in a metadata packet.
4864345d5b57a93ec6d003df84f5cce2db7cccfbd86Igor Murashkin                     */
4872fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin                    ALOGW("%s: ZSL queue frame has no AE state field!",
4882fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin                            __FUNCTION__);
4892fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin                    continue;
4902fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin                }
4912fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin                if (entry.data.u8[0] != ANDROID_CONTROL_AE_STATE_CONVERGED &&
4922fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin                        entry.data.u8[0] != ANDROID_CONTROL_AE_STATE_LOCKED) {
4932fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin                    ALOGVV("%s: ZSL queue frame AE state is %d, need "
4942fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin                           "full capture",  __FUNCTION__, entry.data.u8[0]);
4952fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin                    continue;
4962fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin                }
4972fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin
498754fb0225369123ef6e369fd91c48071dcf6057cYin-Chia Yeh                // Check AF state if device has focuser
499754fb0225369123ef6e369fd91c48071dcf6057cYin-Chia Yeh                if (mHasFocuser) {
500754fb0225369123ef6e369fd91c48071dcf6057cYin-Chia Yeh                    // Make sure the candidate frame has good focus.
501754fb0225369123ef6e369fd91c48071dcf6057cYin-Chia Yeh                    entry = frame.find(ANDROID_CONTROL_AF_STATE);
502754fb0225369123ef6e369fd91c48071dcf6057cYin-Chia Yeh                    if (entry.count == 0) {
503754fb0225369123ef6e369fd91c48071dcf6057cYin-Chia Yeh                        ALOGW("%s: ZSL queue frame has no AF state field!",
504754fb0225369123ef6e369fd91c48071dcf6057cYin-Chia Yeh                                __FUNCTION__);
505754fb0225369123ef6e369fd91c48071dcf6057cYin-Chia Yeh                        continue;
506754fb0225369123ef6e369fd91c48071dcf6057cYin-Chia Yeh                    }
507754fb0225369123ef6e369fd91c48071dcf6057cYin-Chia Yeh                    uint8_t afState = entry.data.u8[0];
508754fb0225369123ef6e369fd91c48071dcf6057cYin-Chia Yeh                    if (afState != ANDROID_CONTROL_AF_STATE_PASSIVE_FOCUSED &&
509754fb0225369123ef6e369fd91c48071dcf6057cYin-Chia Yeh                            afState != ANDROID_CONTROL_AF_STATE_FOCUSED_LOCKED &&
510754fb0225369123ef6e369fd91c48071dcf6057cYin-Chia Yeh                            afState != ANDROID_CONTROL_AF_STATE_NOT_FOCUSED_LOCKED) {
511754fb0225369123ef6e369fd91c48071dcf6057cYin-Chia Yeh                        ALOGW("%s: ZSL queue frame AF state is %d is not good for capture, skip it",
512754fb0225369123ef6e369fd91c48071dcf6057cYin-Chia Yeh                                __FUNCTION__, afState);
513754fb0225369123ef6e369fd91c48071dcf6057cYin-Chia Yeh                        continue;
514754fb0225369123ef6e369fd91c48071dcf6057cYin-Chia Yeh                    }
5157e4c0033c5d2f9d5f53f520a9b0a2fcb8023c810Zhijun He                }
5167e4c0033c5d2f9d5f53f520a9b0a2fcb8023c810Zhijun He
5172fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin                minTimestamp = frameTimestamp;
5182fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin                idx = j;
5192fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin            }
520efb0fd232388b1f726c59f2ec20eea2d3ea8465dIgor Murashkin
521e5729fac81c8a984e984fefc90afc64135817d4fColin Cross            ALOGVV("%s: Saw timestamp %" PRId64, __FUNCTION__, frameTimestamp);
5222fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        }
5232fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    }
5242fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin
5254345d5b57a93ec6d003df84f5cce2db7cccfbd86Igor Murashkin    if (emptyCount == mFrameList.size()) {
5264345d5b57a93ec6d003df84f5cce2db7cccfbd86Igor Murashkin        /**
5274345d5b57a93ec6d003df84f5cce2db7cccfbd86Igor Murashkin         * This could be mildly bad and means our ZSL was triggered before
5284345d5b57a93ec6d003df84f5cce2db7cccfbd86Igor Murashkin         * there were any frames yet received by the camera framework.
5294345d5b57a93ec6d003df84f5cce2db7cccfbd86Igor Murashkin         *
5304345d5b57a93ec6d003df84f5cce2db7cccfbd86Igor Murashkin         * This is a fairly corner case which can happen under:
5314345d5b57a93ec6d003df84f5cce2db7cccfbd86Igor Murashkin         * + a user presses the shutter button real fast when the camera starts
5324345d5b57a93ec6d003df84f5cce2db7cccfbd86Igor Murashkin         *     (startPreview followed immediately by takePicture).
5334345d5b57a93ec6d003df84f5cce2db7cccfbd86Igor Murashkin         * + burst capture case (hitting shutter button as fast possible)
5344345d5b57a93ec6d003df84f5cce2db7cccfbd86Igor Murashkin         *
5354345d5b57a93ec6d003df84f5cce2db7cccfbd86Igor Murashkin         * If this happens in steady case (preview running for a while, call
5364345d5b57a93ec6d003df84f5cce2db7cccfbd86Igor Murashkin         *     a single takePicture) then this might be a fwk bug.
5374345d5b57a93ec6d003df84f5cce2db7cccfbd86Igor Murashkin         */
5384345d5b57a93ec6d003df84f5cce2db7cccfbd86Igor Murashkin        ALOGW("%s: ZSL queue has no metadata frames", __FUNCTION__);
5394345d5b57a93ec6d003df84f5cce2db7cccfbd86Igor Murashkin    }
5404345d5b57a93ec6d003df84f5cce2db7cccfbd86Igor Murashkin
541e5729fac81c8a984e984fefc90afc64135817d4fColin Cross    ALOGV("%s: Candidate timestamp %" PRId64 " (idx %zu), empty frames: %zu",
5424345d5b57a93ec6d003df84f5cce2db7cccfbd86Igor Murashkin          __FUNCTION__, minTimestamp, idx, emptyCount);
5434345d5b57a93ec6d003df84f5cce2db7cccfbd86Igor Murashkin
5442fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    if (metadataIdx) {
5452fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        *metadataIdx = idx;
5462fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    }
5472fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin
5482fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    return minTimestamp;
5492fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin}
5502fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin
5512fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkinvoid ZslProcessor3::onBufferAcquired(const BufferInfo& /*bufferInfo*/) {
5522fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    // Intentionally left empty
5532fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    // Although theoretically we could use this to get better dump info
5542fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin}
5552fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin
5562fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkinvoid ZslProcessor3::onBufferReleased(const BufferInfo& bufferInfo) {
5572fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin
5582fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    // ignore output buffers
5592fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    if (bufferInfo.mOutput) {
5602fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        return;
5612fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    }
5622fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin
5635487fd54f344c422be089217e62098545704bb03Zhijun He    // Lock mutex only once we know this is an input buffer returned to avoid
5645487fd54f344c422be089217e62098545704bb03Zhijun He    // potential deadlock
5655487fd54f344c422be089217e62098545704bb03Zhijun He    Mutex::Autolock l(mInputMutex);
5662fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    // TODO: Verify that the buffer is in our queue by looking at timestamp
5672fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    // theoretically unnecessary unless we change the following assumptions:
5682fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    // -- only 1 buffer reprocessed at a time (which is the case now)
5692fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin
5702fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    // Erase entire ZSL queue since we've now completed the capture and preview
5712fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    // is stopped.
5722fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    //
5732fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    // We need to guarantee that if we do two back-to-back captures,
5742fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    // the second won't use a buffer that's older/the same as the first, which
5752fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    // is theoretically possible if we don't clear out the queue and the
576f0d962a6737eb8eec002d6804d9ffbe7bee672a0Zhijun He    // selection criteria is something like 'newest'. Clearing out the result
577f0d962a6737eb8eec002d6804d9ffbe7bee672a0Zhijun He    // metadata queue on a completed capture ensures we'll only use new timestamp.
578f0d962a6737eb8eec002d6804d9ffbe7bee672a0Zhijun He    // Calling clearZslQueueLocked is a guaranteed deadlock because this callback
579f0d962a6737eb8eec002d6804d9ffbe7bee672a0Zhijun He    // holds the Camera3Stream internal lock (mLock), and clearZslQueueLocked requires
580f0d962a6737eb8eec002d6804d9ffbe7bee672a0Zhijun He    // to hold the same lock.
581f0d962a6737eb8eec002d6804d9ffbe7bee672a0Zhijun He    // TODO: need figure out a way to clear the Zsl buffer queue properly. Right now
582f0d962a6737eb8eec002d6804d9ffbe7bee672a0Zhijun He    // it is safe not to do so, as back to back ZSL capture requires stop and start
583f0d962a6737eb8eec002d6804d9ffbe7bee672a0Zhijun He    // preview, which will flush ZSL queue automatically.
5842fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    ALOGV("%s: Memory optimization, clearing ZSL queue",
5852fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin          __FUNCTION__);
586f0d962a6737eb8eec002d6804d9ffbe7bee672a0Zhijun He    clearZslResultQueueLocked();
5872fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin
5882fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    // Required so we accept more ZSL requests
5892fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    mState = RUNNING;
5902fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin}
5912fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin
5922fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin}; // namespace camera2
5932fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin}; // namespace android
594