CallbackProcessor.cpp revision 893068ad0ca0cce8428f5a358c86b81139399c07
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"));
117deeef54487a34034dc0cfaab20b20d557224c07cMathias Agopian        mCallbackWindow = new Surface(bq);
118d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    }
119d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
120d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    if (mCallbackStreamId != NO_STREAM) {
121d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        // Check if stream parameters have to change
122d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        uint32_t currentWidth, currentHeight, currentFormat;
123d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        res = device->getStreamInfo(mCallbackStreamId,
124d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala                &currentWidth, &currentHeight, &currentFormat);
125d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        if (res != OK) {
126d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            ALOGE("%s: Camera %d: Error querying callback output stream info: "
127d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala                    "%s (%d)", __FUNCTION__, mId,
128d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala                    strerror(-res), res);
129d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            return res;
130d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        }
131d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        if (currentWidth != (uint32_t)params.previewWidth ||
132d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala                currentHeight != (uint32_t)params.previewHeight ||
1334a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala                currentFormat != (uint32_t)callbackFormat) {
134d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            // Since size should only change while preview is not running,
135d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            // assuming that all existing use of old callback stream is
136d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            // completed.
1374a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala            ALOGV("%s: Camera %d: Deleting stream %d since the buffer "
1384a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala                    "parameters changed", __FUNCTION__, mId, mCallbackStreamId);
139d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            res = device->deleteStream(mCallbackStreamId);
140d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            if (res != OK) {
141d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala                ALOGE("%s: Camera %d: Unable to delete old output stream "
1423ee3550a2f529cbf56d87d8503f59a8f45dccf32Eino-Ville Talvala                        "for callbacks: %s (%d)", __FUNCTION__,
14360f11be60f84e79f69e597d158a775c1294e75e9Eino-Ville Talvala                        mId, strerror(-res), res);
144d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala                return res;
145d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            }
146d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            mCallbackStreamId = NO_STREAM;
147d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        }
148d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    }
149d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
150d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    if (mCallbackStreamId == NO_STREAM) {
1514a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala        ALOGV("Creating callback stream: %d x %d, format 0x%x, API format 0x%x",
152d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala                params.previewWidth, params.previewHeight,
1534a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala                callbackFormat, params.previewFormat);
154d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        res = device->createStream(mCallbackWindow,
155d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala                params.previewWidth, params.previewHeight,
1564a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala                callbackFormat, 0, &mCallbackStreamId);
157d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        if (res != OK) {
158d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            ALOGE("%s: Camera %d: Can't create output stream for callbacks: "
159d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala                    "%s (%d)", __FUNCTION__, mId,
160d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala                    strerror(-res), res);
161d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            return res;
162d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        }
163d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    }
164d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
165d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    return OK;
166d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala}
167d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
168d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvalastatus_t CallbackProcessor::deleteStream() {
169d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    ATRACE_CALL();
170d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala    sp<CameraDeviceBase> device;
171a691ff3c03e38e148bbefed35ebb15e552a12613Eino-Ville Talvala    status_t res;
172d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala    {
173d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala        Mutex::Autolock l(mInputMutex);
174d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
175d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala        if (mCallbackStreamId == NO_STREAM) {
176d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala            return OK;
177d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala        }
178d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala        device = mDevice.promote();
179d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala        if (device == 0) {
180d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala            ALOGE("%s: Camera %d: Device does not exist", __FUNCTION__, mId);
181d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala            return INVALID_OPERATION;
182d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala        }
183d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala    }
184a691ff3c03e38e148bbefed35ebb15e552a12613Eino-Ville Talvala    res = device->waitUntilDrained();
185a691ff3c03e38e148bbefed35ebb15e552a12613Eino-Ville Talvala    if (res != OK) {
186a691ff3c03e38e148bbefed35ebb15e552a12613Eino-Ville Talvala        ALOGE("%s: Error waiting for HAL to drain: %s (%d)",
187a691ff3c03e38e148bbefed35ebb15e552a12613Eino-Ville Talvala                __FUNCTION__, strerror(-res), res);
188a691ff3c03e38e148bbefed35ebb15e552a12613Eino-Ville Talvala        return res;
189a691ff3c03e38e148bbefed35ebb15e552a12613Eino-Ville Talvala    }
190a691ff3c03e38e148bbefed35ebb15e552a12613Eino-Ville Talvala
191a691ff3c03e38e148bbefed35ebb15e552a12613Eino-Ville Talvala    res = device->deleteStream(mCallbackStreamId);
192a691ff3c03e38e148bbefed35ebb15e552a12613Eino-Ville Talvala    if (res != OK) {
193a691ff3c03e38e148bbefed35ebb15e552a12613Eino-Ville Talvala        ALOGE("%s: Unable to delete callback stream: %s (%d)",
194a691ff3c03e38e148bbefed35ebb15e552a12613Eino-Ville Talvala                __FUNCTION__, strerror(-res), res);
195a691ff3c03e38e148bbefed35ebb15e552a12613Eino-Ville Talvala        return res;
196a691ff3c03e38e148bbefed35ebb15e552a12613Eino-Ville Talvala    }
197d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
198d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala    {
199d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala        Mutex::Autolock l(mInputMutex);
200cf70d3469332445dc3ffd09729da3538612b1bb2Eino-Ville Talvala
201cf70d3469332445dc3ffd09729da3538612b1bb2Eino-Ville Talvala        mCallbackHeap.clear();
202cf70d3469332445dc3ffd09729da3538612b1bb2Eino-Ville Talvala        mCallbackWindow.clear();
203cf70d3469332445dc3ffd09729da3538612b1bb2Eino-Ville Talvala        mCallbackConsumer.clear();
204cf70d3469332445dc3ffd09729da3538612b1bb2Eino-Ville Talvala
205d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        mCallbackStreamId = NO_STREAM;
206d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    }
207d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    return OK;
208d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala}
209d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
210d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvalaint CallbackProcessor::getStreamId() const {
211d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    Mutex::Autolock l(mInputMutex);
212d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    return mCallbackStreamId;
213d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala}
214d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
215ddf3c5025e2f6f35a4c188c19f30142c64a092c4Igor Murashkinvoid CallbackProcessor::dump(int /*fd*/, const Vector<String16>& /*args*/) const {
216d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala}
217d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
218d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvalabool CallbackProcessor::threadLoop() {
219d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    status_t res;
220d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
221d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    {
222d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        Mutex::Autolock l(mInputMutex);
223d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        while (!mCallbackAvailable) {
224d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            res = mCallbackAvailableSignal.waitRelative(mInputMutex,
225d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala                    kWaitDuration);
226d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            if (res == TIMED_OUT) return true;
227d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        }
228d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        mCallbackAvailable = false;
229d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    }
230d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
231d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    do {
232d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        sp<Camera2Client> client = mClient.promote();
233d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala        if (client == 0) {
234d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala            res = discardNewCallback();
235d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala        } else {
236d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala            res = processNewCallback(client);
237d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala        }
238d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    } while (res == OK);
239d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
240d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    return true;
241d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala}
242d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
243d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvalastatus_t CallbackProcessor::discardNewCallback() {
244d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala    ATRACE_CALL();
245d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala    status_t res;
246d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala    CpuConsumer::LockedBuffer imgBuffer;
247d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala    res = mCallbackConsumer->lockNextBuffer(&imgBuffer);
248d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala    if (res != OK) {
249d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala        if (res != BAD_VALUE) {
250d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala            ALOGE("%s: Camera %d: Error receiving next callback buffer: "
251d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala                    "%s (%d)", __FUNCTION__, mId, strerror(-res), res);
252d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala        }
253d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala        return res;
254d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala    }
255d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala    mCallbackConsumer->unlockBuffer(imgBuffer);
256d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala    return OK;
257d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala}
258d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala
259d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvalastatus_t CallbackProcessor::processNewCallback(sp<Camera2Client> &client) {
260d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    ATRACE_CALL();
261d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    status_t res;
262d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
263d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    sp<Camera2Heap> callbackHeap;
2644a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala    bool useFlexibleYuv = false;
2654a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala    int32_t previewFormat = 0;
266ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He    size_t heapIdx;
267ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He
268d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    {
269ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He        /* acquire SharedParameters before mMutex so we don't dead lock
270ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He            with Camera2Client code calling into StreamingProcessor */
271d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        SharedParameters::Lock l(client->getParameters());
272ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He        Mutex::Autolock m(mInputMutex);
273ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He        CpuConsumer::LockedBuffer imgBuffer;
274ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He        if (mCallbackStreamId == NO_STREAM) {
275ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He            ALOGV("%s: Camera %d:No stream is available"
276ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He                    , __FUNCTION__, mId);
277ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He            return INVALID_OPERATION;
278ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He        }
279ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He
280ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He        ALOGV("%s: Getting buffer", __FUNCTION__);
281ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He        res = mCallbackConsumer->lockNextBuffer(&imgBuffer);
282ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He        if (res != OK) {
283ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He            if (res != BAD_VALUE) {
284ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He                ALOGE("%s: Camera %d: Error receiving next callback buffer: "
285ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He                        "%s (%d)", __FUNCTION__, mId, strerror(-res), res);
286ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He            }
287ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He            return res;
288ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He        }
289ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He        ALOGV("%s: Camera %d: Preview callback available", __FUNCTION__,
290ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He                mId);
291d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
292d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        if ( l.mParameters.state != Parameters::PREVIEW
293d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala                && l.mParameters.state != Parameters::RECORD
294d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala                && l.mParameters.state != Parameters::VIDEO_SNAPSHOT) {
295d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            ALOGV("%s: Camera %d: No longer streaming",
296d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala                    __FUNCTION__, mId);
297d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            mCallbackConsumer->unlockBuffer(imgBuffer);
298d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            return OK;
299d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        }
300d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
301d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        if (! (l.mParameters.previewCallbackFlags &
302d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala                CAMERA_FRAME_CALLBACK_FLAG_ENABLE_MASK) ) {
303d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            ALOGV("%s: No longer enabled, dropping", __FUNCTION__);
304d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            mCallbackConsumer->unlockBuffer(imgBuffer);
305d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            return OK;
306d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        }
307d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        if ((l.mParameters.previewCallbackFlags &
308d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala                        CAMERA_FRAME_CALLBACK_FLAG_ONE_SHOT_MASK) &&
309d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala                !l.mParameters.previewCallbackOneShot) {
310d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            ALOGV("%s: One shot mode, already sent, dropping", __FUNCTION__);
311d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            mCallbackConsumer->unlockBuffer(imgBuffer);
312d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            return OK;
313d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        }
314d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
315893068ad0ca0cce8428f5a358c86b81139399c07Zhijun He        if (imgBuffer.width != static_cast<uint32_t>(l.mParameters.previewWidth) ||
316893068ad0ca0cce8428f5a358c86b81139399c07Zhijun He                imgBuffer.height != static_cast<uint32_t>(l.mParameters.previewHeight)) {
317893068ad0ca0cce8428f5a358c86b81139399c07Zhijun He            ALOGW("%s: The preview size has changed to %d x %d from %d x %d, this buffer is"
318893068ad0ca0cce8428f5a358c86b81139399c07Zhijun He                    " no longer valid, dropping",__FUNCTION__,
319893068ad0ca0cce8428f5a358c86b81139399c07Zhijun He                    l.mParameters.previewWidth, l.mParameters.previewHeight,
320893068ad0ca0cce8428f5a358c86b81139399c07Zhijun He                    imgBuffer.width, imgBuffer.height);
321893068ad0ca0cce8428f5a358c86b81139399c07Zhijun He            mCallbackConsumer->unlockBuffer(imgBuffer);
322893068ad0ca0cce8428f5a358c86b81139399c07Zhijun He            return OK;
323893068ad0ca0cce8428f5a358c86b81139399c07Zhijun He        }
324893068ad0ca0cce8428f5a358c86b81139399c07Zhijun He
3254a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala        previewFormat = l.mParameters.previewFormat;
3264a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala        useFlexibleYuv = l.mParameters.fastInfo.useFlexibleYuv &&
3274a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala                (previewFormat == HAL_PIXEL_FORMAT_YCrCb_420_SP ||
3284a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala                 previewFormat == HAL_PIXEL_FORMAT_YV12);
3294a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala
3304a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala        int32_t expectedFormat = useFlexibleYuv ?
3314a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala                HAL_PIXEL_FORMAT_YCbCr_420_888 : previewFormat;
3324a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala
3334a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala        if (imgBuffer.format != expectedFormat) {
334d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            ALOGE("%s: Camera %d: Unexpected format for callback: "
3354a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala                    "0x%x, expected 0x%x", __FUNCTION__, mId,
3364a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala                    imgBuffer.format, expectedFormat);
337d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            mCallbackConsumer->unlockBuffer(imgBuffer);
338d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            return INVALID_OPERATION;
339d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        }
340d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
341d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        // In one-shot mode, stop sending callbacks after the first one
342d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        if (l.mParameters.previewCallbackFlags &
343d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala                CAMERA_FRAME_CALLBACK_FLAG_ONE_SHOT_MASK) {
344d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            ALOGV("%s: clearing oneshot", __FUNCTION__);
345d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            l.mParameters.previewCallbackOneShot = false;
346d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        }
347d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
348ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He        uint32_t destYStride = 0;
349ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He        uint32_t destCStride = 0;
350ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He        if (useFlexibleYuv) {
351ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He            if (previewFormat == HAL_PIXEL_FORMAT_YV12) {
352ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He                // Strides must align to 16 for YV12
353ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He                destYStride = ALIGN(imgBuffer.width, 16);
354ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He                destCStride = ALIGN(destYStride / 2, 16);
355ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He            } else {
356ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He                // No padding for NV21
357ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He                ALOG_ASSERT(previewFormat == HAL_PIXEL_FORMAT_YCrCb_420_SP,
358ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He                        "Unexpected preview format 0x%x", previewFormat);
359ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He                destYStride = imgBuffer.width;
360ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He                destCStride = destYStride / 2;
361ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He            }
3624a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala        } else {
363ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He            destYStride = imgBuffer.stride;
364ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He            // don't care about cStride
3654a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala        }
3664a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala
367ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He        size_t bufferSize = Camera2Client::calculateBufferSize(
368ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He                imgBuffer.width, imgBuffer.height,
369ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He                previewFormat, destYStride);
370ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He        size_t currentBufferSize = (mCallbackHeap == 0) ?
371ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He                0 : (mCallbackHeap->mHeap->getSize() / kCallbackHeapCount);
372ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He        if (bufferSize != currentBufferSize) {
373ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He            mCallbackHeap.clear();
374ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He            mCallbackHeap = new Camera2Heap(bufferSize, kCallbackHeapCount,
375ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He                    "Camera2Client::CallbackHeap");
376ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He            if (mCallbackHeap->mHeap->getSize() == 0) {
377ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He                ALOGE("%s: Camera %d: Unable to allocate memory for callbacks",
378ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He                        __FUNCTION__, mId);
379ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He                mCallbackConsumer->unlockBuffer(imgBuffer);
380ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He                return INVALID_OPERATION;
381ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He            }
382ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He
383ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He            mCallbackHeapHead = 0;
384ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He            mCallbackHeapFree = kCallbackHeapCount;
385ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He        }
386ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He
387ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He        if (mCallbackHeapFree == 0) {
388ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He            ALOGE("%s: Camera %d: No free callback buffers, dropping frame",
389d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala                    __FUNCTION__, mId);
390d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            mCallbackConsumer->unlockBuffer(imgBuffer);
391ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He            return OK;
392d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        }
393d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
394ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He        heapIdx = mCallbackHeapHead;
395d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
396ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He        mCallbackHeapHead = (mCallbackHeapHead + 1) & kCallbackHeapCount;
397ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He        mCallbackHeapFree--;
398d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
399ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He        // TODO: Get rid of this copy by passing the gralloc queue all the way
400ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He        // to app
401d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
402ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He        ssize_t offset;
403ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He        size_t size;
404ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He        sp<IMemoryHeap> heap =
405ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He                mCallbackHeap->mBuffers[heapIdx]->getMemory(&offset,
406ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He                        &size);
407ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He        uint8_t *data = (uint8_t*)heap->getBase() + offset;
4084a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala
409ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He        if (!useFlexibleYuv) {
410ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He            // Can just memcpy when HAL format matches API format
411ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He            memcpy(data, imgBuffer.data, bufferSize);
412ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He        } else {
413ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He            res = convertFromFlexibleYuv(previewFormat, data, imgBuffer,
414ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He                    destYStride, destCStride);
415ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He            if (res != OK) {
416ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He                ALOGE("%s: Camera %d: Can't convert between 0x%x and 0x%x formats!",
417ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He                        __FUNCTION__, mId, imgBuffer.format, previewFormat);
418ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He                mCallbackConsumer->unlockBuffer(imgBuffer);
419ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He                return BAD_VALUE;
420ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He            }
4214a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala        }
422d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
423ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He        ALOGV("%s: Freeing buffer", __FUNCTION__);
424ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He        mCallbackConsumer->unlockBuffer(imgBuffer);
425e6478de72a8ae1d3abb3e8c20898977c45354a4fEino-Ville Talvala
426e6478de72a8ae1d3abb3e8c20898977c45354a4fEino-Ville Talvala        // mCallbackHeap may get freed up once input mutex is released
427e6478de72a8ae1d3abb3e8c20898977c45354a4fEino-Ville Talvala        callbackHeap = mCallbackHeap;
428ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He    }
429d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
430d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    // Call outside parameter lock to allow re-entrancy from notification
431d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    {
43244cfcf00b9008c1c04f4c8277c6c06af039fd976Igor Murashkin        Camera2Client::SharedCameraCallbacks::Lock
43344cfcf00b9008c1c04f4c8277c6c06af039fd976Igor Murashkin            l(client->mSharedCameraCallbacks);
43444cfcf00b9008c1c04f4c8277c6c06af039fd976Igor Murashkin        if (l.mRemoteCallback != 0) {
435d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            ALOGV("%s: Camera %d: Invoking client data callback",
436d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala                    __FUNCTION__, mId);
43744cfcf00b9008c1c04f4c8277c6c06af039fd976Igor Murashkin            l.mRemoteCallback->dataCallback(CAMERA_MSG_PREVIEW_FRAME,
438e6478de72a8ae1d3abb3e8c20898977c45354a4fEino-Ville Talvala                    callbackHeap->mBuffers[heapIdx], NULL);
439d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        }
440d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    }
441d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
442d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    // Only increment free if we're still using the same heap
443d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    mCallbackHeapFree++;
444d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
445d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    ALOGV("%s: exit", __FUNCTION__);
446d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
447d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    return OK;
448d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala}
449d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
4504a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvalastatus_t CallbackProcessor::convertFromFlexibleYuv(int32_t previewFormat,
4514a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala        uint8_t *dst,
4524a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala        const CpuConsumer::LockedBuffer &src,
4534a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala        uint32_t dstYStride,
4544a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala        uint32_t dstCStride) const {
4554a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala
4564a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala    if (previewFormat != HAL_PIXEL_FORMAT_YCrCb_420_SP &&
4574a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala            previewFormat != HAL_PIXEL_FORMAT_YV12) {
4584a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala        ALOGE("%s: Camera %d: Unexpected preview format when using "
4594a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala                "flexible YUV: 0x%x", __FUNCTION__, mId, previewFormat);
4604a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala        return INVALID_OPERATION;
4614a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala    }
4624a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala
4634a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala    // Copy Y plane, adjusting for stride
4644a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala    const uint8_t *ySrc = src.data;
4654a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala    uint8_t *yDst = dst;
4664a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala    for (size_t row = 0; row < src.height; row++) {
4674a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala        memcpy(yDst, ySrc, src.width);
4684a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala        ySrc += src.stride;
4694a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala        yDst += dstYStride;
4704a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala    }
4714a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala
4724a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala    // Copy/swizzle chroma planes, 4:2:0 subsampling
4739c910c2d780ce1afa221f963da4d4a307443d9beEino-Ville Talvala    const uint8_t *cbSrc = src.dataCb;
4749c910c2d780ce1afa221f963da4d4a307443d9beEino-Ville Talvala    const uint8_t *crSrc = src.dataCr;
4754a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala    size_t chromaHeight = src.height / 2;
4764a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala    size_t chromaWidth = src.width / 2;
4774a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala    ssize_t chromaGap = src.chromaStride -
4784a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala            (chromaWidth * src.chromaStep);
4794a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala    size_t dstChromaGap = dstCStride - chromaWidth;
4804a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala
4814a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala    if (previewFormat == HAL_PIXEL_FORMAT_YCrCb_420_SP) {
4827e66ebc932b4cfa9b4611dffeeb1e91399deb442Eino-Ville Talvala        // Flexible YUV chroma to NV21 chroma
4839c910c2d780ce1afa221f963da4d4a307443d9beEino-Ville Talvala        uint8_t *crcbDst = yDst;
4847e66ebc932b4cfa9b4611dffeeb1e91399deb442Eino-Ville Talvala        // Check for shortcuts
4859c910c2d780ce1afa221f963da4d4a307443d9beEino-Ville Talvala        if (cbSrc == crSrc + 1 && src.chromaStep == 2) {
4869c910c2d780ce1afa221f963da4d4a307443d9beEino-Ville Talvala            ALOGV("%s: Fast NV21->NV21", __FUNCTION__);
4877e66ebc932b4cfa9b4611dffeeb1e91399deb442Eino-Ville Talvala            // Source has semiplanar CrCb chroma layout, can copy by rows
4887e66ebc932b4cfa9b4611dffeeb1e91399deb442Eino-Ville Talvala            for (size_t row = 0; row < chromaHeight; row++) {
4899c910c2d780ce1afa221f963da4d4a307443d9beEino-Ville Talvala                memcpy(crcbDst, crSrc, src.width);
4909c910c2d780ce1afa221f963da4d4a307443d9beEino-Ville Talvala                crcbDst += src.width;
4919c910c2d780ce1afa221f963da4d4a307443d9beEino-Ville Talvala                crSrc += src.chromaStride;
4927e66ebc932b4cfa9b4611dffeeb1e91399deb442Eino-Ville Talvala            }
4937e66ebc932b4cfa9b4611dffeeb1e91399deb442Eino-Ville Talvala        } else {
4949c910c2d780ce1afa221f963da4d4a307443d9beEino-Ville Talvala            ALOGV("%s: Generic->NV21", __FUNCTION__);
4957e66ebc932b4cfa9b4611dffeeb1e91399deb442Eino-Ville Talvala            // Generic copy, always works but not very efficient
4967e66ebc932b4cfa9b4611dffeeb1e91399deb442Eino-Ville Talvala            for (size_t row = 0; row < chromaHeight; row++) {
4977e66ebc932b4cfa9b4611dffeeb1e91399deb442Eino-Ville Talvala                for (size_t col = 0; col < chromaWidth; col++) {
4989c910c2d780ce1afa221f963da4d4a307443d9beEino-Ville Talvala                    *(crcbDst++) = *crSrc;
4999c910c2d780ce1afa221f963da4d4a307443d9beEino-Ville Talvala                    *(crcbDst++) = *cbSrc;
5009c910c2d780ce1afa221f963da4d4a307443d9beEino-Ville Talvala                    crSrc += src.chromaStep;
5019c910c2d780ce1afa221f963da4d4a307443d9beEino-Ville Talvala                    cbSrc += src.chromaStep;
5027e66ebc932b4cfa9b4611dffeeb1e91399deb442Eino-Ville Talvala                }
5039c910c2d780ce1afa221f963da4d4a307443d9beEino-Ville Talvala                crSrc += chromaGap;
5049c910c2d780ce1afa221f963da4d4a307443d9beEino-Ville Talvala                cbSrc += chromaGap;
5054a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala            }
5064a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala        }
5074a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala    } else {
5087e66ebc932b4cfa9b4611dffeeb1e91399deb442Eino-Ville Talvala        // flexible YUV chroma to YV12 chroma
5094a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala        ALOG_ASSERT(previewFormat == HAL_PIXEL_FORMAT_YV12,
5104a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala                "Unexpected preview format 0x%x", previewFormat);
5119c910c2d780ce1afa221f963da4d4a307443d9beEino-Ville Talvala        uint8_t *crDst = yDst;
5129c910c2d780ce1afa221f963da4d4a307443d9beEino-Ville Talvala        uint8_t *cbDst = yDst + chromaHeight * dstCStride;
5137e66ebc932b4cfa9b4611dffeeb1e91399deb442Eino-Ville Talvala        if (src.chromaStep == 1) {
5149c910c2d780ce1afa221f963da4d4a307443d9beEino-Ville Talvala            ALOGV("%s: Fast YV12->YV12", __FUNCTION__);
5157e66ebc932b4cfa9b4611dffeeb1e91399deb442Eino-Ville Talvala            // Source has planar chroma layout, can copy by row
5167e66ebc932b4cfa9b4611dffeeb1e91399deb442Eino-Ville Talvala            for (size_t row = 0; row < chromaHeight; row++) {
5179c910c2d780ce1afa221f963da4d4a307443d9beEino-Ville Talvala                memcpy(crDst, crSrc, chromaWidth);
5189c910c2d780ce1afa221f963da4d4a307443d9beEino-Ville Talvala                crDst += dstCStride;
5199c910c2d780ce1afa221f963da4d4a307443d9beEino-Ville Talvala                crSrc += src.chromaStride;
5207e66ebc932b4cfa9b4611dffeeb1e91399deb442Eino-Ville Talvala            }
5217e66ebc932b4cfa9b4611dffeeb1e91399deb442Eino-Ville Talvala            for (size_t row = 0; row < chromaHeight; row++) {
5229c910c2d780ce1afa221f963da4d4a307443d9beEino-Ville Talvala                memcpy(cbDst, cbSrc, chromaWidth);
5239c910c2d780ce1afa221f963da4d4a307443d9beEino-Ville Talvala                cbDst += dstCStride;
5249c910c2d780ce1afa221f963da4d4a307443d9beEino-Ville Talvala                cbSrc += src.chromaStride;
5257e66ebc932b4cfa9b4611dffeeb1e91399deb442Eino-Ville Talvala            }
5267e66ebc932b4cfa9b4611dffeeb1e91399deb442Eino-Ville Talvala        } else {
5279c910c2d780ce1afa221f963da4d4a307443d9beEino-Ville Talvala            ALOGV("%s: Generic->YV12", __FUNCTION__);
5287e66ebc932b4cfa9b4611dffeeb1e91399deb442Eino-Ville Talvala            // Generic copy, always works but not very efficient
5297e66ebc932b4cfa9b4611dffeeb1e91399deb442Eino-Ville Talvala            for (size_t row = 0; row < chromaHeight; row++) {
5307e66ebc932b4cfa9b4611dffeeb1e91399deb442Eino-Ville Talvala                for (size_t col = 0; col < chromaWidth; col++) {
5319c910c2d780ce1afa221f963da4d4a307443d9beEino-Ville Talvala                    *(crDst++) = *crSrc;
5329c910c2d780ce1afa221f963da4d4a307443d9beEino-Ville Talvala                    *(cbDst++) = *cbSrc;
5339c910c2d780ce1afa221f963da4d4a307443d9beEino-Ville Talvala                    crSrc += src.chromaStep;
5349c910c2d780ce1afa221f963da4d4a307443d9beEino-Ville Talvala                    cbSrc += src.chromaStep;
5357e66ebc932b4cfa9b4611dffeeb1e91399deb442Eino-Ville Talvala                }
5369c910c2d780ce1afa221f963da4d4a307443d9beEino-Ville Talvala                crSrc += chromaGap;
5379c910c2d780ce1afa221f963da4d4a307443d9beEino-Ville Talvala                cbSrc += chromaGap;
5389c910c2d780ce1afa221f963da4d4a307443d9beEino-Ville Talvala                crDst += dstChromaGap;
5399c910c2d780ce1afa221f963da4d4a307443d9beEino-Ville Talvala                cbDst += dstChromaGap;
5404a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala            }
5414a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala        }
5424a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala    }
5434a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala
5444a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala    return OK;
5454a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala}
5464a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala
547d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala}; // namespace camera2
548d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala}; // namespace android
549