CallbackProcessor.cpp revision 7b82efe7a376c882f8f938e1c41b8311a8cdda4a
1d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala/*
2d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala * Copyright (C) 2012 The Android Open Source Project
3d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala *
4d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala * Licensed under the Apache License, Version 2.0 (the "License");
5d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala * you may not use this file except in compliance with the License.
6d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala * You may obtain a copy of the License at
7d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala *
8d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala *      http://www.apache.org/licenses/LICENSE-2.0
9d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala *
10d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala * Unless required by applicable law or agreed to in writing, software
11d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala * distributed under the License is distributed on an "AS IS" BASIS,
12d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala * See the License for the specific language governing permissions and
14d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala * limitations under the License.
15d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala */
16d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
174bb8118816874c696d9f1adab48490df1da365f7Eino-Ville Talvala#define LOG_TAG "Camera2-CallbackProcessor"
18d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala#define ATRACE_TAG ATRACE_TAG_CAMERA
19d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala//#define LOG_NDEBUG 0
20d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
21d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala#include <utils/Log.h>
22d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala#include <utils/Trace.h>
231a2952aee048ca7b1765e2bc09ebe9aeddaeafa3Mathias Agopian#include <gui/Surface.h>
247b82efe7a376c882f8f938e1c41b8311a8cdda4aEino-Ville Talvala
257b82efe7a376c882f8f938e1c41b8311a8cdda4aEino-Ville Talvala#include "common/CameraDeviceBase.h"
267b82efe7a376c882f8f938e1c41b8311a8cdda4aEino-Ville Talvala#include "api1/Camera2Client.h"
277b82efe7a376c882f8f938e1c41b8311a8cdda4aEino-Ville Talvala#include "api1/client2/CallbackProcessor.h"
28d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
294a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala#define ALIGN(x, mask) ( ((x) + (mask) - 1) & ~((mask) - 1) )
30d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
31d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvalanamespace android {
32d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvalanamespace camera2 {
33d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
34d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville TalvalaCallbackProcessor::CallbackProcessor(sp<Camera2Client> client):
35d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        Thread(false),
36d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        mClient(client),
37d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala        mDevice(client->getCameraDevice()),
38d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala        mId(client->getCameraId()),
39d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        mCallbackAvailable(false),
403ee3550a2f529cbf56d87d8503f59a8f45dccf32Eino-Ville Talvala        mCallbackToApp(false),
41d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        mCallbackStreamId(NO_STREAM) {
42d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala}
43d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
44d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville TalvalaCallbackProcessor::~CallbackProcessor() {
45d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    ALOGV("%s: Exit", __FUNCTION__);
46cf70d3469332445dc3ffd09729da3538612b1bb2Eino-Ville Talvala    deleteStream();
47d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala}
48d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
49d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvalavoid CallbackProcessor::onFrameAvailable() {
50d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    Mutex::Autolock l(mInputMutex);
51d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    if (!mCallbackAvailable) {
52d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        mCallbackAvailable = true;
53d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        mCallbackAvailableSignal.signal();
54d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    }
55d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala}
56d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
573ee3550a2f529cbf56d87d8503f59a8f45dccf32Eino-Ville Talvalastatus_t CallbackProcessor::setCallbackWindow(
583ee3550a2f529cbf56d87d8503f59a8f45dccf32Eino-Ville Talvala        sp<ANativeWindow> callbackWindow) {
593ee3550a2f529cbf56d87d8503f59a8f45dccf32Eino-Ville Talvala    ATRACE_CALL();
603ee3550a2f529cbf56d87d8503f59a8f45dccf32Eino-Ville Talvala    status_t res;
613ee3550a2f529cbf56d87d8503f59a8f45dccf32Eino-Ville Talvala
623ee3550a2f529cbf56d87d8503f59a8f45dccf32Eino-Ville Talvala    Mutex::Autolock l(mInputMutex);
633ee3550a2f529cbf56d87d8503f59a8f45dccf32Eino-Ville Talvala
643ee3550a2f529cbf56d87d8503f59a8f45dccf32Eino-Ville Talvala    sp<Camera2Client> client = mClient.promote();
653ee3550a2f529cbf56d87d8503f59a8f45dccf32Eino-Ville Talvala    if (client == 0) return OK;
663ee3550a2f529cbf56d87d8503f59a8f45dccf32Eino-Ville Talvala    sp<CameraDeviceBase> device = client->getCameraDevice();
673ee3550a2f529cbf56d87d8503f59a8f45dccf32Eino-Ville Talvala
683ee3550a2f529cbf56d87d8503f59a8f45dccf32Eino-Ville Talvala    // If the window is changing, clear out stream if it already exists
693ee3550a2f529cbf56d87d8503f59a8f45dccf32Eino-Ville Talvala    if (mCallbackWindow != callbackWindow && mCallbackStreamId != NO_STREAM) {
703ee3550a2f529cbf56d87d8503f59a8f45dccf32Eino-Ville Talvala        res = device->deleteStream(mCallbackStreamId);
713ee3550a2f529cbf56d87d8503f59a8f45dccf32Eino-Ville Talvala        if (res != OK) {
723ee3550a2f529cbf56d87d8503f59a8f45dccf32Eino-Ville Talvala            ALOGE("%s: Camera %d: Unable to delete old stream "
733ee3550a2f529cbf56d87d8503f59a8f45dccf32Eino-Ville Talvala                    "for callbacks: %s (%d)", __FUNCTION__,
743ee3550a2f529cbf56d87d8503f59a8f45dccf32Eino-Ville Talvala                    client->getCameraId(), strerror(-res), res);
753ee3550a2f529cbf56d87d8503f59a8f45dccf32Eino-Ville Talvala            return res;
763ee3550a2f529cbf56d87d8503f59a8f45dccf32Eino-Ville Talvala        }
773ee3550a2f529cbf56d87d8503f59a8f45dccf32Eino-Ville Talvala        mCallbackStreamId = NO_STREAM;
783ee3550a2f529cbf56d87d8503f59a8f45dccf32Eino-Ville Talvala        mCallbackConsumer.clear();
793ee3550a2f529cbf56d87d8503f59a8f45dccf32Eino-Ville Talvala    }
803ee3550a2f529cbf56d87d8503f59a8f45dccf32Eino-Ville Talvala    mCallbackWindow = callbackWindow;
813ee3550a2f529cbf56d87d8503f59a8f45dccf32Eino-Ville Talvala    mCallbackToApp = (mCallbackWindow != NULL);
823ee3550a2f529cbf56d87d8503f59a8f45dccf32Eino-Ville Talvala
833ee3550a2f529cbf56d87d8503f59a8f45dccf32Eino-Ville Talvala    return OK;
843ee3550a2f529cbf56d87d8503f59a8f45dccf32Eino-Ville Talvala}
853ee3550a2f529cbf56d87d8503f59a8f45dccf32Eino-Ville Talvala
86d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvalastatus_t CallbackProcessor::updateStream(const Parameters &params) {
87d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    ATRACE_CALL();
88d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    status_t res;
89d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
90d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    Mutex::Autolock l(mInputMutex);
91d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
92d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala    sp<CameraDeviceBase> device = mDevice.promote();
93d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala    if (device == 0) {
94d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala        ALOGE("%s: Camera %d: Device does not exist", __FUNCTION__, mId);
95d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala        return INVALID_OPERATION;
96d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala    }
97d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
984a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala    // If possible, use the flexible YUV format
994a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala    int32_t callbackFormat = params.previewFormat;
1007167849162e046606ffdbfa6a94fadd8f0518af2Eino-Ville Talvala    if (mCallbackToApp) {
1017167849162e046606ffdbfa6a94fadd8f0518af2Eino-Ville Talvala        // TODO: etalvala: This should use the flexible YUV format as well, but
1027167849162e046606ffdbfa6a94fadd8f0518af2Eino-Ville Talvala        // need to reconcile HAL2/HAL3 requirements.
1037167849162e046606ffdbfa6a94fadd8f0518af2Eino-Ville Talvala        callbackFormat = HAL_PIXEL_FORMAT_YV12;
1047167849162e046606ffdbfa6a94fadd8f0518af2Eino-Ville Talvala    } else if(params.fastInfo.useFlexibleYuv &&
1054a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala            (params.previewFormat == HAL_PIXEL_FORMAT_YCrCb_420_SP ||
1064a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala             params.previewFormat == HAL_PIXEL_FORMAT_YV12) ) {
1074a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala        callbackFormat = HAL_PIXEL_FORMAT_YCbCr_420_888;
1084a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala    }
1094a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala
1103ee3550a2f529cbf56d87d8503f59a8f45dccf32Eino-Ville Talvala    if (!mCallbackToApp && mCallbackConsumer == 0) {
1113ee3550a2f529cbf56d87d8503f59a8f45dccf32Eino-Ville Talvala        // Create CPU buffer queue endpoint, since app hasn't given us one
11225d729c3aba847cb4b56b1e6ca143410faca76c8Eino-Ville Talvala        // Make it async to avoid disconnect deadlocks
1138d764bfc74c40641f018a0aa87d6f484aec92eaeMathias Agopian        sp<BufferQueue> bq = new BufferQueue();
1145e1f08b3917ac7900f8a11118afb7e8bf3e61c64Mathias Agopian        mCallbackConsumer = new CpuConsumer(bq, kCallbackHeapCount);
115d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        mCallbackConsumer->setFrameAvailableListener(this);
116d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        mCallbackConsumer->setName(String8("Camera2Client::CallbackConsumer"));
1171a2952aee048ca7b1765e2bc09ebe9aeddaeafa3Mathias Agopian        mCallbackWindow = new Surface(
118d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            mCallbackConsumer->getProducerInterface());
119d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    }
120d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
121d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    if (mCallbackStreamId != NO_STREAM) {
122d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        // Check if stream parameters have to change
123d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        uint32_t currentWidth, currentHeight, currentFormat;
124d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        res = device->getStreamInfo(mCallbackStreamId,
125d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala                &currentWidth, &currentHeight, &currentFormat);
126d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        if (res != OK) {
127d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            ALOGE("%s: Camera %d: Error querying callback output stream info: "
128d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala                    "%s (%d)", __FUNCTION__, mId,
129d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala                    strerror(-res), res);
130d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            return res;
131d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        }
132d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        if (currentWidth != (uint32_t)params.previewWidth ||
133d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala                currentHeight != (uint32_t)params.previewHeight ||
1344a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala                currentFormat != (uint32_t)callbackFormat) {
135d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            // Since size should only change while preview is not running,
136d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            // assuming that all existing use of old callback stream is
137d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            // completed.
1384a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala            ALOGV("%s: Camera %d: Deleting stream %d since the buffer "
1394a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala                    "parameters changed", __FUNCTION__, mId, mCallbackStreamId);
140d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            res = device->deleteStream(mCallbackStreamId);
141d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            if (res != OK) {
142d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala                ALOGE("%s: Camera %d: Unable to delete old output stream "
1433ee3550a2f529cbf56d87d8503f59a8f45dccf32Eino-Ville Talvala                        "for callbacks: %s (%d)", __FUNCTION__,
14460f11be60f84e79f69e597d158a775c1294e75e9Eino-Ville Talvala                        mId, strerror(-res), res);
145d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala                return res;
146d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            }
147d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            mCallbackStreamId = NO_STREAM;
148d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        }
149d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    }
150d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
151d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    if (mCallbackStreamId == NO_STREAM) {
1524a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala        ALOGV("Creating callback stream: %d x %d, format 0x%x, API format 0x%x",
153d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala                params.previewWidth, params.previewHeight,
1544a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala                callbackFormat, params.previewFormat);
155d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        res = device->createStream(mCallbackWindow,
156d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala                params.previewWidth, params.previewHeight,
1574a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala                callbackFormat, 0, &mCallbackStreamId);
158d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        if (res != OK) {
159d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            ALOGE("%s: Camera %d: Can't create output stream for callbacks: "
160d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala                    "%s (%d)", __FUNCTION__, mId,
161d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala                    strerror(-res), res);
162d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            return res;
163d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        }
164d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    }
165d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
166d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    return OK;
167d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala}
168d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
169d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvalastatus_t CallbackProcessor::deleteStream() {
170d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    ATRACE_CALL();
171d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala    sp<CameraDeviceBase> device;
172a691ff3c03e38e148bbefed35ebb15e552a12613Eino-Ville Talvala    status_t res;
173d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala    {
174d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala        Mutex::Autolock l(mInputMutex);
175d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
176d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala        if (mCallbackStreamId == NO_STREAM) {
177d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala            return OK;
178d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala        }
179d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala        device = mDevice.promote();
180d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala        if (device == 0) {
181d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala            ALOGE("%s: Camera %d: Device does not exist", __FUNCTION__, mId);
182d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala            return INVALID_OPERATION;
183d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala        }
184d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala    }
185a691ff3c03e38e148bbefed35ebb15e552a12613Eino-Ville Talvala    res = device->waitUntilDrained();
186a691ff3c03e38e148bbefed35ebb15e552a12613Eino-Ville Talvala    if (res != OK) {
187a691ff3c03e38e148bbefed35ebb15e552a12613Eino-Ville Talvala        ALOGE("%s: Error waiting for HAL to drain: %s (%d)",
188a691ff3c03e38e148bbefed35ebb15e552a12613Eino-Ville Talvala                __FUNCTION__, strerror(-res), res);
189a691ff3c03e38e148bbefed35ebb15e552a12613Eino-Ville Talvala        return res;
190a691ff3c03e38e148bbefed35ebb15e552a12613Eino-Ville Talvala    }
191a691ff3c03e38e148bbefed35ebb15e552a12613Eino-Ville Talvala
192a691ff3c03e38e148bbefed35ebb15e552a12613Eino-Ville Talvala    res = device->deleteStream(mCallbackStreamId);
193a691ff3c03e38e148bbefed35ebb15e552a12613Eino-Ville Talvala    if (res != OK) {
194a691ff3c03e38e148bbefed35ebb15e552a12613Eino-Ville Talvala        ALOGE("%s: Unable to delete callback stream: %s (%d)",
195a691ff3c03e38e148bbefed35ebb15e552a12613Eino-Ville Talvala                __FUNCTION__, strerror(-res), res);
196a691ff3c03e38e148bbefed35ebb15e552a12613Eino-Ville Talvala        return res;
197a691ff3c03e38e148bbefed35ebb15e552a12613Eino-Ville Talvala    }
198d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
199d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala    {
200d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala        Mutex::Autolock l(mInputMutex);
201cf70d3469332445dc3ffd09729da3538612b1bb2Eino-Ville Talvala
202cf70d3469332445dc3ffd09729da3538612b1bb2Eino-Ville Talvala        mCallbackHeap.clear();
203cf70d3469332445dc3ffd09729da3538612b1bb2Eino-Ville Talvala        mCallbackWindow.clear();
204cf70d3469332445dc3ffd09729da3538612b1bb2Eino-Ville Talvala        mCallbackConsumer.clear();
205cf70d3469332445dc3ffd09729da3538612b1bb2Eino-Ville Talvala
206d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        mCallbackStreamId = NO_STREAM;
207d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    }
208d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    return OK;
209d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala}
210d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
211d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvalaint CallbackProcessor::getStreamId() const {
212d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    Mutex::Autolock l(mInputMutex);
213d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    return mCallbackStreamId;
214d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala}
215d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
216ddf3c5025e2f6f35a4c188c19f30142c64a092c4Igor Murashkinvoid CallbackProcessor::dump(int /*fd*/, const Vector<String16>& /*args*/) const {
217d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala}
218d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
219d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvalabool CallbackProcessor::threadLoop() {
220d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    status_t res;
221d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
222d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    {
223d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        Mutex::Autolock l(mInputMutex);
224d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        while (!mCallbackAvailable) {
225d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            res = mCallbackAvailableSignal.waitRelative(mInputMutex,
226d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala                    kWaitDuration);
227d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            if (res == TIMED_OUT) return true;
228d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        }
229d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        mCallbackAvailable = false;
230d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    }
231d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
232d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    do {
233d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        sp<Camera2Client> client = mClient.promote();
234d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala        if (client == 0) {
235d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala            res = discardNewCallback();
236d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala        } else {
237d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala            res = processNewCallback(client);
238d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala        }
239d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    } while (res == OK);
240d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
241d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    return true;
242d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala}
243d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
244d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvalastatus_t CallbackProcessor::discardNewCallback() {
245d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala    ATRACE_CALL();
246d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala    status_t res;
247d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala    CpuConsumer::LockedBuffer imgBuffer;
248d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala    res = mCallbackConsumer->lockNextBuffer(&imgBuffer);
249d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala    if (res != OK) {
250d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala        if (res != BAD_VALUE) {
251d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala            ALOGE("%s: Camera %d: Error receiving next callback buffer: "
252d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala                    "%s (%d)", __FUNCTION__, mId, strerror(-res), res);
253d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala        }
254d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala        return res;
255d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala    }
256d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala    mCallbackConsumer->unlockBuffer(imgBuffer);
257d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala    return OK;
258d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala}
259d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala
260d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvalastatus_t CallbackProcessor::processNewCallback(sp<Camera2Client> &client) {
261d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    ATRACE_CALL();
262d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    status_t res;
263d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
264d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    sp<Camera2Heap> callbackHeap;
2654a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala    bool useFlexibleYuv = false;
2664a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala    int32_t previewFormat = 0;
267ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He    size_t heapIdx;
268ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He
269d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    {
270ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He        /* acquire SharedParameters before mMutex so we don't dead lock
271ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He            with Camera2Client code calling into StreamingProcessor */
272d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        SharedParameters::Lock l(client->getParameters());
273ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He        Mutex::Autolock m(mInputMutex);
274ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He        CpuConsumer::LockedBuffer imgBuffer;
275ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He        if (mCallbackStreamId == NO_STREAM) {
276ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He            ALOGV("%s: Camera %d:No stream is available"
277ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He                    , __FUNCTION__, mId);
278ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He            return INVALID_OPERATION;
279ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He        }
280ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He
281ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He        ALOGV("%s: Getting buffer", __FUNCTION__);
282ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He        res = mCallbackConsumer->lockNextBuffer(&imgBuffer);
283ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He        if (res != OK) {
284ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He            if (res != BAD_VALUE) {
285ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He                ALOGE("%s: Camera %d: Error receiving next callback buffer: "
286ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He                        "%s (%d)", __FUNCTION__, mId, strerror(-res), res);
287ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He            }
288ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He            return res;
289ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He        }
290ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He        ALOGV("%s: Camera %d: Preview callback available", __FUNCTION__,
291ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He                mId);
292d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
293d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        if ( l.mParameters.state != Parameters::PREVIEW
294d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala                && l.mParameters.state != Parameters::RECORD
295d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala                && l.mParameters.state != Parameters::VIDEO_SNAPSHOT) {
296d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            ALOGV("%s: Camera %d: No longer streaming",
297d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala                    __FUNCTION__, mId);
298d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            mCallbackConsumer->unlockBuffer(imgBuffer);
299d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            return OK;
300d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        }
301d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
302d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        if (! (l.mParameters.previewCallbackFlags &
303d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala                CAMERA_FRAME_CALLBACK_FLAG_ENABLE_MASK) ) {
304d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            ALOGV("%s: No longer enabled, dropping", __FUNCTION__);
305d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            mCallbackConsumer->unlockBuffer(imgBuffer);
306d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            return OK;
307d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        }
308d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        if ((l.mParameters.previewCallbackFlags &
309d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala                        CAMERA_FRAME_CALLBACK_FLAG_ONE_SHOT_MASK) &&
310d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala                !l.mParameters.previewCallbackOneShot) {
311d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            ALOGV("%s: One shot mode, already sent, dropping", __FUNCTION__);
312d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            mCallbackConsumer->unlockBuffer(imgBuffer);
313d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            return OK;
314d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        }
315d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
3164a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala        previewFormat = l.mParameters.previewFormat;
3174a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala        useFlexibleYuv = l.mParameters.fastInfo.useFlexibleYuv &&
3184a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala                (previewFormat == HAL_PIXEL_FORMAT_YCrCb_420_SP ||
3194a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala                 previewFormat == HAL_PIXEL_FORMAT_YV12);
3204a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala
3214a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala        int32_t expectedFormat = useFlexibleYuv ?
3224a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala                HAL_PIXEL_FORMAT_YCbCr_420_888 : previewFormat;
3234a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala
3244a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala        if (imgBuffer.format != expectedFormat) {
325d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            ALOGE("%s: Camera %d: Unexpected format for callback: "
3264a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala                    "0x%x, expected 0x%x", __FUNCTION__, mId,
3274a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala                    imgBuffer.format, expectedFormat);
328d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            mCallbackConsumer->unlockBuffer(imgBuffer);
329d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            return INVALID_OPERATION;
330d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        }
331d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
332d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        // In one-shot mode, stop sending callbacks after the first one
333d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        if (l.mParameters.previewCallbackFlags &
334d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala                CAMERA_FRAME_CALLBACK_FLAG_ONE_SHOT_MASK) {
335d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            ALOGV("%s: clearing oneshot", __FUNCTION__);
336d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            l.mParameters.previewCallbackOneShot = false;
337d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        }
338d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
339ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He        uint32_t destYStride = 0;
340ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He        uint32_t destCStride = 0;
341ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He        if (useFlexibleYuv) {
342ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He            if (previewFormat == HAL_PIXEL_FORMAT_YV12) {
343ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He                // Strides must align to 16 for YV12
344ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He                destYStride = ALIGN(imgBuffer.width, 16);
345ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He                destCStride = ALIGN(destYStride / 2, 16);
346ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He            } else {
347ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He                // No padding for NV21
348ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He                ALOG_ASSERT(previewFormat == HAL_PIXEL_FORMAT_YCrCb_420_SP,
349ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He                        "Unexpected preview format 0x%x", previewFormat);
350ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He                destYStride = imgBuffer.width;
351ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He                destCStride = destYStride / 2;
352ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He            }
3534a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala        } else {
354ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He            destYStride = imgBuffer.stride;
355ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He            // don't care about cStride
3564a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala        }
3574a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala
358ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He        size_t bufferSize = Camera2Client::calculateBufferSize(
359ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He                imgBuffer.width, imgBuffer.height,
360ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He                previewFormat, destYStride);
361ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He        size_t currentBufferSize = (mCallbackHeap == 0) ?
362ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He                0 : (mCallbackHeap->mHeap->getSize() / kCallbackHeapCount);
363ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He        if (bufferSize != currentBufferSize) {
364ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He            mCallbackHeap.clear();
365ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He            mCallbackHeap = new Camera2Heap(bufferSize, kCallbackHeapCount,
366ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He                    "Camera2Client::CallbackHeap");
367ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He            if (mCallbackHeap->mHeap->getSize() == 0) {
368ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He                ALOGE("%s: Camera %d: Unable to allocate memory for callbacks",
369ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He                        __FUNCTION__, mId);
370ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He                mCallbackConsumer->unlockBuffer(imgBuffer);
371ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He                return INVALID_OPERATION;
372ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He            }
373ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He
374ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He            mCallbackHeapHead = 0;
375ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He            mCallbackHeapFree = kCallbackHeapCount;
376ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He        }
377ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He
378ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He        if (mCallbackHeapFree == 0) {
379ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He            ALOGE("%s: Camera %d: No free callback buffers, dropping frame",
380d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala                    __FUNCTION__, mId);
381d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            mCallbackConsumer->unlockBuffer(imgBuffer);
382ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He            return OK;
383d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        }
384d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
385ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He        heapIdx = mCallbackHeapHead;
386d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
387ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He        mCallbackHeapHead = (mCallbackHeapHead + 1) & kCallbackHeapCount;
388ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He        mCallbackHeapFree--;
389d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
390ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He        // TODO: Get rid of this copy by passing the gralloc queue all the way
391ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He        // to app
392d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
393ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He        ssize_t offset;
394ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He        size_t size;
395ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He        sp<IMemoryHeap> heap =
396ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He                mCallbackHeap->mBuffers[heapIdx]->getMemory(&offset,
397ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He                        &size);
398ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He        uint8_t *data = (uint8_t*)heap->getBase() + offset;
3994a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala
400ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He        if (!useFlexibleYuv) {
401ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He            // Can just memcpy when HAL format matches API format
402ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He            memcpy(data, imgBuffer.data, bufferSize);
403ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He        } else {
404ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He            res = convertFromFlexibleYuv(previewFormat, data, imgBuffer,
405ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He                    destYStride, destCStride);
406ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He            if (res != OK) {
407ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He                ALOGE("%s: Camera %d: Can't convert between 0x%x and 0x%x formats!",
408ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He                        __FUNCTION__, mId, imgBuffer.format, previewFormat);
409ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He                mCallbackConsumer->unlockBuffer(imgBuffer);
410ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He                return BAD_VALUE;
411ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He            }
4124a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala        }
413d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
414ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He        ALOGV("%s: Freeing buffer", __FUNCTION__);
415ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He        mCallbackConsumer->unlockBuffer(imgBuffer);
416e6478de72a8ae1d3abb3e8c20898977c45354a4fEino-Ville Talvala
417e6478de72a8ae1d3abb3e8c20898977c45354a4fEino-Ville Talvala        // mCallbackHeap may get freed up once input mutex is released
418e6478de72a8ae1d3abb3e8c20898977c45354a4fEino-Ville Talvala        callbackHeap = mCallbackHeap;
419ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He    }
420d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
421d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    // Call outside parameter lock to allow re-entrancy from notification
422d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    {
42344cfcf00b9008c1c04f4c8277c6c06af039fd976Igor Murashkin        Camera2Client::SharedCameraCallbacks::Lock
42444cfcf00b9008c1c04f4c8277c6c06af039fd976Igor Murashkin            l(client->mSharedCameraCallbacks);
42544cfcf00b9008c1c04f4c8277c6c06af039fd976Igor Murashkin        if (l.mRemoteCallback != 0) {
426d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            ALOGV("%s: Camera %d: Invoking client data callback",
427d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala                    __FUNCTION__, mId);
42844cfcf00b9008c1c04f4c8277c6c06af039fd976Igor Murashkin            l.mRemoteCallback->dataCallback(CAMERA_MSG_PREVIEW_FRAME,
429e6478de72a8ae1d3abb3e8c20898977c45354a4fEino-Ville Talvala                    callbackHeap->mBuffers[heapIdx], NULL);
430d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        }
431d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    }
432d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
433d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    // Only increment free if we're still using the same heap
434d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    mCallbackHeapFree++;
435d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
436d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    ALOGV("%s: exit", __FUNCTION__);
437d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
438d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    return OK;
439d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala}
440d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
4414a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvalastatus_t CallbackProcessor::convertFromFlexibleYuv(int32_t previewFormat,
4424a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala        uint8_t *dst,
4434a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala        const CpuConsumer::LockedBuffer &src,
4444a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala        uint32_t dstYStride,
4454a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala        uint32_t dstCStride) const {
4464a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala
4474a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala    if (previewFormat != HAL_PIXEL_FORMAT_YCrCb_420_SP &&
4484a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala            previewFormat != HAL_PIXEL_FORMAT_YV12) {
4494a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala        ALOGE("%s: Camera %d: Unexpected preview format when using "
4504a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala                "flexible YUV: 0x%x", __FUNCTION__, mId, previewFormat);
4514a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala        return INVALID_OPERATION;
4524a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala    }
4534a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala
4544a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala    // Copy Y plane, adjusting for stride
4554a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala    const uint8_t *ySrc = src.data;
4564a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala    uint8_t *yDst = dst;
4574a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala    for (size_t row = 0; row < src.height; row++) {
4584a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala        memcpy(yDst, ySrc, src.width);
4594a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala        ySrc += src.stride;
4604a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala        yDst += dstYStride;
4614a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala    }
4624a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala
4634a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala    // Copy/swizzle chroma planes, 4:2:0 subsampling
4649c910c2d780ce1afa221f963da4d4a307443d9beEino-Ville Talvala    const uint8_t *cbSrc = src.dataCb;
4659c910c2d780ce1afa221f963da4d4a307443d9beEino-Ville Talvala    const uint8_t *crSrc = src.dataCr;
4664a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala    size_t chromaHeight = src.height / 2;
4674a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala    size_t chromaWidth = src.width / 2;
4684a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala    ssize_t chromaGap = src.chromaStride -
4694a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala            (chromaWidth * src.chromaStep);
4704a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala    size_t dstChromaGap = dstCStride - chromaWidth;
4714a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala
4724a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala    if (previewFormat == HAL_PIXEL_FORMAT_YCrCb_420_SP) {
4737e66ebc932b4cfa9b4611dffeeb1e91399deb442Eino-Ville Talvala        // Flexible YUV chroma to NV21 chroma
4749c910c2d780ce1afa221f963da4d4a307443d9beEino-Ville Talvala        uint8_t *crcbDst = yDst;
4757e66ebc932b4cfa9b4611dffeeb1e91399deb442Eino-Ville Talvala        // Check for shortcuts
4769c910c2d780ce1afa221f963da4d4a307443d9beEino-Ville Talvala        if (cbSrc == crSrc + 1 && src.chromaStep == 2) {
4779c910c2d780ce1afa221f963da4d4a307443d9beEino-Ville Talvala            ALOGV("%s: Fast NV21->NV21", __FUNCTION__);
4787e66ebc932b4cfa9b4611dffeeb1e91399deb442Eino-Ville Talvala            // Source has semiplanar CrCb chroma layout, can copy by rows
4797e66ebc932b4cfa9b4611dffeeb1e91399deb442Eino-Ville Talvala            for (size_t row = 0; row < chromaHeight; row++) {
4809c910c2d780ce1afa221f963da4d4a307443d9beEino-Ville Talvala                memcpy(crcbDst, crSrc, src.width);
4819c910c2d780ce1afa221f963da4d4a307443d9beEino-Ville Talvala                crcbDst += src.width;
4829c910c2d780ce1afa221f963da4d4a307443d9beEino-Ville Talvala                crSrc += src.chromaStride;
4837e66ebc932b4cfa9b4611dffeeb1e91399deb442Eino-Ville Talvala            }
4847e66ebc932b4cfa9b4611dffeeb1e91399deb442Eino-Ville Talvala        } else {
4859c910c2d780ce1afa221f963da4d4a307443d9beEino-Ville Talvala            ALOGV("%s: Generic->NV21", __FUNCTION__);
4867e66ebc932b4cfa9b4611dffeeb1e91399deb442Eino-Ville Talvala            // Generic copy, always works but not very efficient
4877e66ebc932b4cfa9b4611dffeeb1e91399deb442Eino-Ville Talvala            for (size_t row = 0; row < chromaHeight; row++) {
4887e66ebc932b4cfa9b4611dffeeb1e91399deb442Eino-Ville Talvala                for (size_t col = 0; col < chromaWidth; col++) {
4899c910c2d780ce1afa221f963da4d4a307443d9beEino-Ville Talvala                    *(crcbDst++) = *crSrc;
4909c910c2d780ce1afa221f963da4d4a307443d9beEino-Ville Talvala                    *(crcbDst++) = *cbSrc;
4919c910c2d780ce1afa221f963da4d4a307443d9beEino-Ville Talvala                    crSrc += src.chromaStep;
4929c910c2d780ce1afa221f963da4d4a307443d9beEino-Ville Talvala                    cbSrc += src.chromaStep;
4937e66ebc932b4cfa9b4611dffeeb1e91399deb442Eino-Ville Talvala                }
4949c910c2d780ce1afa221f963da4d4a307443d9beEino-Ville Talvala                crSrc += chromaGap;
4959c910c2d780ce1afa221f963da4d4a307443d9beEino-Ville Talvala                cbSrc += chromaGap;
4964a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala            }
4974a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala        }
4984a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala    } else {
4997e66ebc932b4cfa9b4611dffeeb1e91399deb442Eino-Ville Talvala        // flexible YUV chroma to YV12 chroma
5004a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala        ALOG_ASSERT(previewFormat == HAL_PIXEL_FORMAT_YV12,
5014a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala                "Unexpected preview format 0x%x", previewFormat);
5029c910c2d780ce1afa221f963da4d4a307443d9beEino-Ville Talvala        uint8_t *crDst = yDst;
5039c910c2d780ce1afa221f963da4d4a307443d9beEino-Ville Talvala        uint8_t *cbDst = yDst + chromaHeight * dstCStride;
5047e66ebc932b4cfa9b4611dffeeb1e91399deb442Eino-Ville Talvala        if (src.chromaStep == 1) {
5059c910c2d780ce1afa221f963da4d4a307443d9beEino-Ville Talvala            ALOGV("%s: Fast YV12->YV12", __FUNCTION__);
5067e66ebc932b4cfa9b4611dffeeb1e91399deb442Eino-Ville Talvala            // Source has planar chroma layout, can copy by row
5077e66ebc932b4cfa9b4611dffeeb1e91399deb442Eino-Ville Talvala            for (size_t row = 0; row < chromaHeight; row++) {
5089c910c2d780ce1afa221f963da4d4a307443d9beEino-Ville Talvala                memcpy(crDst, crSrc, chromaWidth);
5099c910c2d780ce1afa221f963da4d4a307443d9beEino-Ville Talvala                crDst += dstCStride;
5109c910c2d780ce1afa221f963da4d4a307443d9beEino-Ville Talvala                crSrc += src.chromaStride;
5117e66ebc932b4cfa9b4611dffeeb1e91399deb442Eino-Ville Talvala            }
5127e66ebc932b4cfa9b4611dffeeb1e91399deb442Eino-Ville Talvala            for (size_t row = 0; row < chromaHeight; row++) {
5139c910c2d780ce1afa221f963da4d4a307443d9beEino-Ville Talvala                memcpy(cbDst, cbSrc, chromaWidth);
5149c910c2d780ce1afa221f963da4d4a307443d9beEino-Ville Talvala                cbDst += dstCStride;
5159c910c2d780ce1afa221f963da4d4a307443d9beEino-Ville Talvala                cbSrc += src.chromaStride;
5167e66ebc932b4cfa9b4611dffeeb1e91399deb442Eino-Ville Talvala            }
5177e66ebc932b4cfa9b4611dffeeb1e91399deb442Eino-Ville Talvala        } else {
5189c910c2d780ce1afa221f963da4d4a307443d9beEino-Ville Talvala            ALOGV("%s: Generic->YV12", __FUNCTION__);
5197e66ebc932b4cfa9b4611dffeeb1e91399deb442Eino-Ville Talvala            // Generic copy, always works but not very efficient
5207e66ebc932b4cfa9b4611dffeeb1e91399deb442Eino-Ville Talvala            for (size_t row = 0; row < chromaHeight; row++) {
5217e66ebc932b4cfa9b4611dffeeb1e91399deb442Eino-Ville Talvala                for (size_t col = 0; col < chromaWidth; col++) {
5229c910c2d780ce1afa221f963da4d4a307443d9beEino-Ville Talvala                    *(crDst++) = *crSrc;
5239c910c2d780ce1afa221f963da4d4a307443d9beEino-Ville Talvala                    *(cbDst++) = *cbSrc;
5249c910c2d780ce1afa221f963da4d4a307443d9beEino-Ville Talvala                    crSrc += src.chromaStep;
5259c910c2d780ce1afa221f963da4d4a307443d9beEino-Ville Talvala                    cbSrc += src.chromaStep;
5267e66ebc932b4cfa9b4611dffeeb1e91399deb442Eino-Ville Talvala                }
5279c910c2d780ce1afa221f963da4d4a307443d9beEino-Ville Talvala                crSrc += chromaGap;
5289c910c2d780ce1afa221f963da4d4a307443d9beEino-Ville Talvala                cbSrc += chromaGap;
5299c910c2d780ce1afa221f963da4d4a307443d9beEino-Ville Talvala                crDst += dstChromaGap;
5309c910c2d780ce1afa221f963da4d4a307443d9beEino-Ville Talvala                cbDst += dstChromaGap;
5314a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala            }
5324a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala        }
5334a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala    }
5344a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala
5354a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala    return OK;
5364a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala}
5374a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala
538d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala}; // namespace camera2
539d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala}; // namespace android
540