CallbackProcessor.cpp revision 7167849162e046606ffdbfa6a94fadd8f0518af2
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>
23d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
24d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala#include "CallbackProcessor.h"
251a2952aee048ca7b1765e2bc09ebe9aeddaeafa3Mathias Agopian#include <gui/Surface.h>
26b99c5b8eebb35133a08c46b015624bd4c4a6c477Eino-Ville Talvala#include "../CameraDeviceBase.h"
27d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala#include "../Camera2Client.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
112d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        mCallbackConsumer = new CpuConsumer(kCallbackHeapCount);
113d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        mCallbackConsumer->setFrameAvailableListener(this);
114d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        mCallbackConsumer->setName(String8("Camera2Client::CallbackConsumer"));
1151a2952aee048ca7b1765e2bc09ebe9aeddaeafa3Mathias Agopian        mCallbackWindow = new Surface(
116d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            mCallbackConsumer->getProducerInterface());
117d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    }
118d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
119d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    if (mCallbackStreamId != NO_STREAM) {
120d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        // Check if stream parameters have to change
121d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        uint32_t currentWidth, currentHeight, currentFormat;
122d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        res = device->getStreamInfo(mCallbackStreamId,
123d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala                &currentWidth, &currentHeight, &currentFormat);
124d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        if (res != OK) {
125d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            ALOGE("%s: Camera %d: Error querying callback output stream info: "
126d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala                    "%s (%d)", __FUNCTION__, mId,
127d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala                    strerror(-res), res);
128d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            return res;
129d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        }
130d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        if (currentWidth != (uint32_t)params.previewWidth ||
131d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala                currentHeight != (uint32_t)params.previewHeight ||
1324a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala                currentFormat != (uint32_t)callbackFormat) {
133d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            // Since size should only change while preview is not running,
134d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            // assuming that all existing use of old callback stream is
135d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            // completed.
1364a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala            ALOGV("%s: Camera %d: Deleting stream %d since the buffer "
1374a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala                    "parameters changed", __FUNCTION__, mId, mCallbackStreamId);
138d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            res = device->deleteStream(mCallbackStreamId);
139d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            if (res != OK) {
140d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala                ALOGE("%s: Camera %d: Unable to delete old output stream "
1413ee3550a2f529cbf56d87d8503f59a8f45dccf32Eino-Ville Talvala                        "for callbacks: %s (%d)", __FUNCTION__,
14260f11be60f84e79f69e597d158a775c1294e75e9Eino-Ville Talvala                        mId, strerror(-res), res);
143d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala                return res;
144d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            }
145d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            mCallbackStreamId = NO_STREAM;
146d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        }
147d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    }
148d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
149d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    if (mCallbackStreamId == NO_STREAM) {
1504a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala        ALOGV("Creating callback stream: %d x %d, format 0x%x, API format 0x%x",
151d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala                params.previewWidth, params.previewHeight,
1524a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala                callbackFormat, params.previewFormat);
153d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        res = device->createStream(mCallbackWindow,
154d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala                params.previewWidth, params.previewHeight,
1554a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala                callbackFormat, 0, &mCallbackStreamId);
156d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        if (res != OK) {
157d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            ALOGE("%s: Camera %d: Can't create output stream for callbacks: "
158d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala                    "%s (%d)", __FUNCTION__, mId,
159d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala                    strerror(-res), res);
160d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            return res;
161d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        }
162d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    }
163d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
164d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    return OK;
165d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala}
166d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
167d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvalastatus_t CallbackProcessor::deleteStream() {
168d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    ATRACE_CALL();
169d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala    sp<CameraDeviceBase> device;
170d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
171d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala    {
172d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala        Mutex::Autolock l(mInputMutex);
173d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
174d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala        if (mCallbackStreamId == NO_STREAM) {
175d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala            return OK;
176d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala        }
177d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala        device = mDevice.promote();
178d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala        if (device == 0) {
179d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala            ALOGE("%s: Camera %d: Device does not exist", __FUNCTION__, mId);
180d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala            return INVALID_OPERATION;
181d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala        }
182d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala    }
183d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala    device->deleteStream(mCallbackStreamId);
184d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
185d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala    {
186d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala        Mutex::Autolock l(mInputMutex);
187cf70d3469332445dc3ffd09729da3538612b1bb2Eino-Ville Talvala
188cf70d3469332445dc3ffd09729da3538612b1bb2Eino-Ville Talvala        mCallbackHeap.clear();
189cf70d3469332445dc3ffd09729da3538612b1bb2Eino-Ville Talvala        mCallbackWindow.clear();
190cf70d3469332445dc3ffd09729da3538612b1bb2Eino-Ville Talvala        mCallbackConsumer.clear();
191cf70d3469332445dc3ffd09729da3538612b1bb2Eino-Ville Talvala
192d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        mCallbackStreamId = NO_STREAM;
193d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    }
194d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    return OK;
195d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala}
196d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
197d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvalaint CallbackProcessor::getStreamId() const {
198d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    Mutex::Autolock l(mInputMutex);
199d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    return mCallbackStreamId;
200d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala}
201d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
202ddf3c5025e2f6f35a4c188c19f30142c64a092c4Igor Murashkinvoid CallbackProcessor::dump(int /*fd*/, const Vector<String16>& /*args*/) const {
203d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala}
204d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
205d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvalabool CallbackProcessor::threadLoop() {
206d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    status_t res;
207d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
208d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    {
209d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        Mutex::Autolock l(mInputMutex);
210d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        while (!mCallbackAvailable) {
211d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            res = mCallbackAvailableSignal.waitRelative(mInputMutex,
212d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala                    kWaitDuration);
213d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            if (res == TIMED_OUT) return true;
214d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        }
215d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        mCallbackAvailable = false;
216d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    }
217d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
218d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    do {
219d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        sp<Camera2Client> client = mClient.promote();
220d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala        if (client == 0) {
221d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala            res = discardNewCallback();
222d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala        } else {
223d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala            res = processNewCallback(client);
224d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala        }
225d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    } while (res == OK);
226d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
227d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    return true;
228d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala}
229d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
230d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvalastatus_t CallbackProcessor::discardNewCallback() {
231d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala    ATRACE_CALL();
232d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala    status_t res;
233d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala    CpuConsumer::LockedBuffer imgBuffer;
234d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala    res = mCallbackConsumer->lockNextBuffer(&imgBuffer);
235d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala    if (res != OK) {
236d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala        if (res != BAD_VALUE) {
237d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala            ALOGE("%s: Camera %d: Error receiving next callback buffer: "
238d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala                    "%s (%d)", __FUNCTION__, mId, strerror(-res), res);
239d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala        }
240d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala        return res;
241d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala    }
242d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala    mCallbackConsumer->unlockBuffer(imgBuffer);
243d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala    return OK;
244d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala}
245d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala
246d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvalastatus_t CallbackProcessor::processNewCallback(sp<Camera2Client> &client) {
247d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    ATRACE_CALL();
248d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    status_t res;
249d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
250d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    sp<Camera2Heap> callbackHeap;
251d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    size_t heapIdx;
252d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
253d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    CpuConsumer::LockedBuffer imgBuffer;
254d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    ALOGV("%s: Getting buffer", __FUNCTION__);
255d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    res = mCallbackConsumer->lockNextBuffer(&imgBuffer);
256d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    if (res != OK) {
257d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        if (res != BAD_VALUE) {
258d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            ALOGE("%s: Camera %d: Error receiving next callback buffer: "
259d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala                    "%s (%d)", __FUNCTION__, mId, strerror(-res), res);
260d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        }
261d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        return res;
262d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    }
263d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    ALOGV("%s: Camera %d: Preview callback available", __FUNCTION__,
264d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala            mId);
265d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
2664a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala    bool useFlexibleYuv = false;
2674a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala    int32_t previewFormat = 0;
268d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    {
269d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        SharedParameters::Lock l(client->getParameters());
270d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
271d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        if ( l.mParameters.state != Parameters::PREVIEW
272d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala                && l.mParameters.state != Parameters::RECORD
273d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala                && l.mParameters.state != Parameters::VIDEO_SNAPSHOT) {
274d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            ALOGV("%s: Camera %d: No longer streaming",
275d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala                    __FUNCTION__, mId);
276d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            mCallbackConsumer->unlockBuffer(imgBuffer);
277d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            return OK;
278d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        }
279d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
280d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        if (! (l.mParameters.previewCallbackFlags &
281d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala                CAMERA_FRAME_CALLBACK_FLAG_ENABLE_MASK) ) {
282d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            ALOGV("%s: No longer enabled, dropping", __FUNCTION__);
283d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            mCallbackConsumer->unlockBuffer(imgBuffer);
284d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            return OK;
285d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        }
286d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        if ((l.mParameters.previewCallbackFlags &
287d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala                        CAMERA_FRAME_CALLBACK_FLAG_ONE_SHOT_MASK) &&
288d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala                !l.mParameters.previewCallbackOneShot) {
289d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            ALOGV("%s: One shot mode, already sent, dropping", __FUNCTION__);
290d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            mCallbackConsumer->unlockBuffer(imgBuffer);
291d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            return OK;
292d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        }
293d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
2944a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala        previewFormat = l.mParameters.previewFormat;
2954a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala        useFlexibleYuv = l.mParameters.fastInfo.useFlexibleYuv &&
2964a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala                (previewFormat == HAL_PIXEL_FORMAT_YCrCb_420_SP ||
2974a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala                 previewFormat == HAL_PIXEL_FORMAT_YV12);
2984a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala
2994a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala        int32_t expectedFormat = useFlexibleYuv ?
3004a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala                HAL_PIXEL_FORMAT_YCbCr_420_888 : previewFormat;
3014a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala
3024a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala        if (imgBuffer.format != expectedFormat) {
303d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            ALOGE("%s: Camera %d: Unexpected format for callback: "
3044a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala                    "0x%x, expected 0x%x", __FUNCTION__, mId,
3054a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala                    imgBuffer.format, expectedFormat);
306d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            mCallbackConsumer->unlockBuffer(imgBuffer);
307d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            return INVALID_OPERATION;
308d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        }
309d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
310d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        // In one-shot mode, stop sending callbacks after the first one
311d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        if (l.mParameters.previewCallbackFlags &
312d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala                CAMERA_FRAME_CALLBACK_FLAG_ONE_SHOT_MASK) {
313d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            ALOGV("%s: clearing oneshot", __FUNCTION__);
314d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            l.mParameters.previewCallbackOneShot = false;
315d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        }
316d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    }
317d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
3184a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala    uint32_t destYStride = 0;
3194a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala    uint32_t destCStride = 0;
3204a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala    if (useFlexibleYuv) {
3214a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala        if (previewFormat == HAL_PIXEL_FORMAT_YV12) {
3224a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala            // Strides must align to 16 for YV12
3234a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala            destYStride = ALIGN(imgBuffer.width, 16);
3244a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala            destCStride = ALIGN(destYStride / 2, 16);
3254a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala        } else {
3264a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala            // No padding for NV21
3274a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala            ALOG_ASSERT(previewFormat == HAL_PIXEL_FORMAT_YCrCb_420_SP,
3284a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala                    "Unexpected preview format 0x%x", previewFormat);
3294a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala            destYStride = imgBuffer.width;
3304a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala            destCStride = destYStride / 2;
3314a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala        }
3324a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala    } else {
3334a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala        destYStride = imgBuffer.stride;
3344a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala        // don't care about cStride
3354a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala    }
3364a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala
337d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    size_t bufferSize = Camera2Client::calculateBufferSize(
338d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            imgBuffer.width, imgBuffer.height,
3394a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala            previewFormat, destYStride);
340d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    size_t currentBufferSize = (mCallbackHeap == 0) ?
341d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            0 : (mCallbackHeap->mHeap->getSize() / kCallbackHeapCount);
342d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    if (bufferSize != currentBufferSize) {
343d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        mCallbackHeap.clear();
344d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        mCallbackHeap = new Camera2Heap(bufferSize, kCallbackHeapCount,
345d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala                "Camera2Client::CallbackHeap");
346d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        if (mCallbackHeap->mHeap->getSize() == 0) {
347d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            ALOGE("%s: Camera %d: Unable to allocate memory for callbacks",
348d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala                    __FUNCTION__, mId);
349d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            mCallbackConsumer->unlockBuffer(imgBuffer);
350d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            return INVALID_OPERATION;
351d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        }
352d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
353d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        mCallbackHeapHead = 0;
354d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        mCallbackHeapFree = kCallbackHeapCount;
355d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    }
356d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
357d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    if (mCallbackHeapFree == 0) {
358d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        ALOGE("%s: Camera %d: No free callback buffers, dropping frame",
359d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala                __FUNCTION__, mId);
360d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        mCallbackConsumer->unlockBuffer(imgBuffer);
361d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        return OK;
362d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    }
363d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
364d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    heapIdx = mCallbackHeapHead;
365d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
366d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    mCallbackHeapHead = (mCallbackHeapHead + 1) & kCallbackHeapCount;
367d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    mCallbackHeapFree--;
368d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
3694a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala    // TODO: Get rid of this copy by passing the gralloc queue all the way
370d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    // to app
371d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
372d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    ssize_t offset;
373d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    size_t size;
374d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    sp<IMemoryHeap> heap =
375d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            mCallbackHeap->mBuffers[heapIdx]->getMemory(&offset,
376d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala                    &size);
377d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    uint8_t *data = (uint8_t*)heap->getBase() + offset;
3784a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala
3794a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala    if (!useFlexibleYuv) {
3804a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala        // Can just memcpy when HAL format matches API format
3814a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala        memcpy(data, imgBuffer.data, bufferSize);
3824a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala    } else {
3834a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala        res = convertFromFlexibleYuv(previewFormat, data, imgBuffer,
3844a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala                destYStride, destCStride);
3854a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala        if (res != OK) {
3864a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala            ALOGE("%s: Camera %d: Can't convert between 0x%x and 0x%x formats!",
3874a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala                    __FUNCTION__, mId, imgBuffer.format, previewFormat);
3884a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala            mCallbackConsumer->unlockBuffer(imgBuffer);
3894a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala            return BAD_VALUE;
3904a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala        }
3914a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala    }
392d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
393d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    ALOGV("%s: Freeing buffer", __FUNCTION__);
394d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    mCallbackConsumer->unlockBuffer(imgBuffer);
395d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
396d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    // Call outside parameter lock to allow re-entrancy from notification
397d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    {
39844cfcf00b9008c1c04f4c8277c6c06af039fd976Igor Murashkin        Camera2Client::SharedCameraCallbacks::Lock
39944cfcf00b9008c1c04f4c8277c6c06af039fd976Igor Murashkin            l(client->mSharedCameraCallbacks);
40044cfcf00b9008c1c04f4c8277c6c06af039fd976Igor Murashkin        if (l.mRemoteCallback != 0) {
401d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            ALOGV("%s: Camera %d: Invoking client data callback",
402d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala                    __FUNCTION__, mId);
40344cfcf00b9008c1c04f4c8277c6c06af039fd976Igor Murashkin            l.mRemoteCallback->dataCallback(CAMERA_MSG_PREVIEW_FRAME,
404d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala                    mCallbackHeap->mBuffers[heapIdx], NULL);
405d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        }
406d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    }
407d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
408d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    // Only increment free if we're still using the same heap
409d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    mCallbackHeapFree++;
410d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
411d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    ALOGV("%s: exit", __FUNCTION__);
412d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
413d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    return OK;
414d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala}
415d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
4164a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvalastatus_t CallbackProcessor::convertFromFlexibleYuv(int32_t previewFormat,
4174a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala        uint8_t *dst,
4184a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala        const CpuConsumer::LockedBuffer &src,
4194a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala        uint32_t dstYStride,
4204a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala        uint32_t dstCStride) const {
4214a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala
4224a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala    if (previewFormat != HAL_PIXEL_FORMAT_YCrCb_420_SP &&
4234a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala            previewFormat != HAL_PIXEL_FORMAT_YV12) {
4244a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala        ALOGE("%s: Camera %d: Unexpected preview format when using "
4254a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala                "flexible YUV: 0x%x", __FUNCTION__, mId, previewFormat);
4264a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala        return INVALID_OPERATION;
4274a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala    }
4284a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala
4294a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala    // Copy Y plane, adjusting for stride
4304a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala    const uint8_t *ySrc = src.data;
4314a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala    uint8_t *yDst = dst;
4324a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala    for (size_t row = 0; row < src.height; row++) {
4334a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala        memcpy(yDst, ySrc, src.width);
4344a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala        ySrc += src.stride;
4354a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala        yDst += dstYStride;
4364a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala    }
4374a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala
4384a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala    // Copy/swizzle chroma planes, 4:2:0 subsampling
4394a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala    const uint8_t *uSrc = src.dataCb;
4404a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala    const uint8_t *vSrc = src.dataCr;
4414a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala    size_t chromaHeight = src.height / 2;
4424a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala    size_t chromaWidth = src.width / 2;
4434a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala    ssize_t chromaGap = src.chromaStride -
4444a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala            (chromaWidth * src.chromaStep);
4454a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala    size_t dstChromaGap = dstCStride - chromaWidth;
4464a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala
4474a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala    if (previewFormat == HAL_PIXEL_FORMAT_YCrCb_420_SP) {
4484a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala        // NV21
4494a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala        uint8_t *vuDst = yDst;
4504a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala        for (size_t row = 0; row < chromaHeight; row++) {
4514a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala            for (size_t col = 0; col < chromaWidth; col++) {
4524a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala                *(vuDst++) = *vSrc;
4534a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala                *(vuDst++) = *uSrc;
4544a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala                vSrc += src.chromaStep;
4554a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala                uSrc += src.chromaStep;
4564a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala            }
4574a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala            vSrc += chromaGap;
4584a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala            uSrc += chromaGap;
4594a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala        }
4604a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala    } else {
4614a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala        // YV12
4624a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala        ALOG_ASSERT(previewFormat == HAL_PIXEL_FORMAT_YV12,
4634a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala                "Unexpected preview format 0x%x", previewFormat);
4644a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala        uint8_t *vDst = yDst;
4654a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala        uint8_t *uDst = yDst + chromaHeight * dstCStride;
4664a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala        for (size_t row = 0; row < chromaHeight; row++) {
4674a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala            for (size_t col = 0; col < chromaWidth; col++) {
4684a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala                *(vDst++) = *vSrc;
4694a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala                *(uDst++) = *uSrc;
4704a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala                vSrc += src.chromaStep;
4714a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala                uSrc += src.chromaStep;
4724a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala            }
4734a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala            vSrc += chromaGap;
4744a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala            uSrc += chromaGap;
4754a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala            vDst += dstChromaGap;
4764a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala            uDst += dstChromaGap;
4774a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala        }
4784a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala    }
4794a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala
4804a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala    return OK;
4814a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala}
4824a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala
483d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala}; // namespace camera2
484d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala}; // namespace android
485