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
4904f101c35eaa90b1f95939afac30674ec1611e6fDan Stozavoid CallbackProcessor::onFrameAvailable(const BufferItem& /*item*/) {
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(
588b0b971b1416738f22488a80be726d1ec12552a8Chih-Hung Hsieh        const sp<Surface>& 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
1138aa0f0619ea867e8fb240cf27913d4f8ae767385Dan Stoza        sp<IGraphicBufferProducer> producer;
1148aa0f0619ea867e8fb240cf27913d4f8ae767385Dan Stoza        sp<IGraphicBufferConsumer> consumer;
1158aa0f0619ea867e8fb240cf27913d4f8ae767385Dan Stoza        BufferQueue::createBufferQueue(&producer, &consumer);
1168aa0f0619ea867e8fb240cf27913d4f8ae767385Dan Stoza        mCallbackConsumer = new CpuConsumer(consumer, kCallbackHeapCount);
117d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        mCallbackConsumer->setFrameAvailableListener(this);
118727d172137b4f32681c098de8e2623c0b65a6406Eino-Ville Talvala        mCallbackConsumer->setName(String8("Camera2-CallbackConsumer"));
1198aa0f0619ea867e8fb240cf27913d4f8ae767385Dan Stoza        mCallbackWindow = new Surface(producer);
120d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    }
121d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
122d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    if (mCallbackStreamId != NO_STREAM) {
123d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        // Check if stream parameters have to change
124d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        uint32_t currentWidth, currentHeight, currentFormat;
125d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        res = device->getStreamInfo(mCallbackStreamId,
126d46a6b9fd8b2a4f9098757384711e2cd03a91651Eino-Ville Talvala                &currentWidth, &currentHeight, &currentFormat, 0);
127d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        if (res != OK) {
128d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            ALOGE("%s: Camera %d: Error querying callback output stream info: "
129d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala                    "%s (%d)", __FUNCTION__, mId,
130d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala                    strerror(-res), res);
131d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            return res;
132d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        }
133d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        if (currentWidth != (uint32_t)params.previewWidth ||
134d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala                currentHeight != (uint32_t)params.previewHeight ||
1354a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala                currentFormat != (uint32_t)callbackFormat) {
136d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            // Since size should only change while preview is not running,
137d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            // assuming that all existing use of old callback stream is
138d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            // completed.
1394a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala            ALOGV("%s: Camera %d: Deleting stream %d since the buffer "
1404a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala                    "parameters changed", __FUNCTION__, mId, mCallbackStreamId);
141d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            res = device->deleteStream(mCallbackStreamId);
142d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            if (res != OK) {
143d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala                ALOGE("%s: Camera %d: Unable to delete old output stream "
1443ee3550a2f529cbf56d87d8503f59a8f45dccf32Eino-Ville Talvala                        "for callbacks: %s (%d)", __FUNCTION__,
14560f11be60f84e79f69e597d158a775c1294e75e9Eino-Ville Talvala                        mId, strerror(-res), res);
146d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala                return res;
147d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            }
148d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            mCallbackStreamId = NO_STREAM;
149d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        }
150d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    }
151d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
152d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    if (mCallbackStreamId == NO_STREAM) {
1534a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala        ALOGV("Creating callback stream: %d x %d, format 0x%x, API format 0x%x",
154d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala                params.previewWidth, params.previewHeight,
1554a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala                callbackFormat, params.previewFormat);
156d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        res = device->createStream(mCallbackWindow,
157b97babb8c08969b55af3b6456d15f764c8873d3fYin-Chia Yeh                params.previewWidth, params.previewHeight, callbackFormat,
1582cbf6cea23539bfe99e36d1d221de62255452e86Eino-Ville Talvala                HAL_DATASPACE_V0_JFIF, CAMERA3_STREAM_ROTATION_0, &mCallbackStreamId);
159d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        if (res != OK) {
160d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            ALOGE("%s: Camera %d: Can't create output stream for callbacks: "
161d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala                    "%s (%d)", __FUNCTION__, mId,
162d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala                    strerror(-res), res);
163d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            return res;
164d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        }
165d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    }
166d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
167d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    return OK;
168d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala}
169d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
170d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvalastatus_t CallbackProcessor::deleteStream() {
171d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    ATRACE_CALL();
172d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala    sp<CameraDeviceBase> device;
173a691ff3c03e38e148bbefed35ebb15e552a12613Eino-Ville Talvala    status_t res;
174d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala    {
175d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala        Mutex::Autolock l(mInputMutex);
176d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
177d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala        if (mCallbackStreamId == NO_STREAM) {
178d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala            return OK;
179d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala        }
180d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala        device = mDevice.promote();
181d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala        if (device == 0) {
182d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala            ALOGE("%s: Camera %d: Device does not exist", __FUNCTION__, mId);
183d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala            return INVALID_OPERATION;
184d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala        }
185d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala    }
186a691ff3c03e38e148bbefed35ebb15e552a12613Eino-Ville Talvala    res = device->waitUntilDrained();
187a691ff3c03e38e148bbefed35ebb15e552a12613Eino-Ville Talvala    if (res != OK) {
188a691ff3c03e38e148bbefed35ebb15e552a12613Eino-Ville Talvala        ALOGE("%s: Error waiting for HAL to drain: %s (%d)",
189a691ff3c03e38e148bbefed35ebb15e552a12613Eino-Ville Talvala                __FUNCTION__, strerror(-res), res);
190a691ff3c03e38e148bbefed35ebb15e552a12613Eino-Ville Talvala        return res;
191a691ff3c03e38e148bbefed35ebb15e552a12613Eino-Ville Talvala    }
192a691ff3c03e38e148bbefed35ebb15e552a12613Eino-Ville Talvala
193a691ff3c03e38e148bbefed35ebb15e552a12613Eino-Ville Talvala    res = device->deleteStream(mCallbackStreamId);
194a691ff3c03e38e148bbefed35ebb15e552a12613Eino-Ville Talvala    if (res != OK) {
195a691ff3c03e38e148bbefed35ebb15e552a12613Eino-Ville Talvala        ALOGE("%s: Unable to delete callback stream: %s (%d)",
196a691ff3c03e38e148bbefed35ebb15e552a12613Eino-Ville Talvala                __FUNCTION__, strerror(-res), res);
197a691ff3c03e38e148bbefed35ebb15e552a12613Eino-Ville Talvala        return res;
198a691ff3c03e38e148bbefed35ebb15e552a12613Eino-Ville Talvala    }
199d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
200d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala    {
201d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala        Mutex::Autolock l(mInputMutex);
202cf70d3469332445dc3ffd09729da3538612b1bb2Eino-Ville Talvala
203cf70d3469332445dc3ffd09729da3538612b1bb2Eino-Ville Talvala        mCallbackHeap.clear();
204cf70d3469332445dc3ffd09729da3538612b1bb2Eino-Ville Talvala        mCallbackWindow.clear();
205cf70d3469332445dc3ffd09729da3538612b1bb2Eino-Ville Talvala        mCallbackConsumer.clear();
206cf70d3469332445dc3ffd09729da3538612b1bb2Eino-Ville Talvala
207d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        mCallbackStreamId = NO_STREAM;
208d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    }
209d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    return OK;
210d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala}
211d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
212d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvalaint CallbackProcessor::getStreamId() const {
213d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    Mutex::Autolock l(mInputMutex);
214d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    return mCallbackStreamId;
215d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala}
216d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
217ddf3c5025e2f6f35a4c188c19f30142c64a092c4Igor Murashkinvoid CallbackProcessor::dump(int /*fd*/, const Vector<String16>& /*args*/) const {
218d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala}
219d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
220d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvalabool CallbackProcessor::threadLoop() {
221d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    status_t res;
222d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
223d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    {
224d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        Mutex::Autolock l(mInputMutex);
225d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        while (!mCallbackAvailable) {
226d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            res = mCallbackAvailableSignal.waitRelative(mInputMutex,
227d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala                    kWaitDuration);
228d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            if (res == TIMED_OUT) return true;
229d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        }
230d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        mCallbackAvailable = false;
231d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    }
232d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
233d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    do {
234d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        sp<Camera2Client> client = mClient.promote();
235d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala        if (client == 0) {
236d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala            res = discardNewCallback();
237d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala        } else {
238d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala            res = processNewCallback(client);
239d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala        }
240d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    } while (res == OK);
241d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
242d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    return true;
243d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala}
244d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
245d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvalastatus_t CallbackProcessor::discardNewCallback() {
246d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala    ATRACE_CALL();
247d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala    status_t res;
248d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala    CpuConsumer::LockedBuffer imgBuffer;
249d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala    res = mCallbackConsumer->lockNextBuffer(&imgBuffer);
250d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala    if (res != OK) {
251d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala        if (res != BAD_VALUE) {
252d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala            ALOGE("%s: Camera %d: Error receiving next callback buffer: "
253d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala                    "%s (%d)", __FUNCTION__, mId, strerror(-res), res);
254d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala        }
255d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala        return res;
256d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala    }
257d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala    mCallbackConsumer->unlockBuffer(imgBuffer);
258d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala    return OK;
259d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala}
260d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala
261d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvalastatus_t CallbackProcessor::processNewCallback(sp<Camera2Client> &client) {
262d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    ATRACE_CALL();
263d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    status_t res;
264d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
265d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    sp<Camera2Heap> callbackHeap;
2664a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala    bool useFlexibleYuv = false;
2674a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala    int32_t previewFormat = 0;
268ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He    size_t heapIdx;
269ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He
270d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    {
271ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He        /* acquire SharedParameters before mMutex so we don't dead lock
272ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He            with Camera2Client code calling into StreamingProcessor */
273d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        SharedParameters::Lock l(client->getParameters());
274ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He        Mutex::Autolock m(mInputMutex);
275ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He        CpuConsumer::LockedBuffer imgBuffer;
276ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He        if (mCallbackStreamId == NO_STREAM) {
277ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He            ALOGV("%s: Camera %d:No stream is available"
278ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He                    , __FUNCTION__, mId);
279ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He            return INVALID_OPERATION;
280ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He        }
281ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He
282ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He        ALOGV("%s: Getting buffer", __FUNCTION__);
283ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He        res = mCallbackConsumer->lockNextBuffer(&imgBuffer);
284ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He        if (res != OK) {
285ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He            if (res != BAD_VALUE) {
286ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He                ALOGE("%s: Camera %d: Error receiving next callback buffer: "
287ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He                        "%s (%d)", __FUNCTION__, mId, strerror(-res), res);
288ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He            }
289ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He            return res;
290ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He        }
291ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He        ALOGV("%s: Camera %d: Preview callback available", __FUNCTION__,
292ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He                mId);
293d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
294d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        if ( l.mParameters.state != Parameters::PREVIEW
295d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala                && l.mParameters.state != Parameters::RECORD
296d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala                && l.mParameters.state != Parameters::VIDEO_SNAPSHOT) {
297d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            ALOGV("%s: Camera %d: No longer streaming",
298d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala                    __FUNCTION__, mId);
299d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            mCallbackConsumer->unlockBuffer(imgBuffer);
300d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            return OK;
301d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        }
302d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
303d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        if (! (l.mParameters.previewCallbackFlags &
304d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala                CAMERA_FRAME_CALLBACK_FLAG_ENABLE_MASK) ) {
305d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            ALOGV("%s: No longer enabled, dropping", __FUNCTION__);
306d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            mCallbackConsumer->unlockBuffer(imgBuffer);
307d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            return OK;
308d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        }
309d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        if ((l.mParameters.previewCallbackFlags &
310d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala                        CAMERA_FRAME_CALLBACK_FLAG_ONE_SHOT_MASK) &&
311d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala                !l.mParameters.previewCallbackOneShot) {
312d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            ALOGV("%s: One shot mode, already sent, dropping", __FUNCTION__);
313d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            mCallbackConsumer->unlockBuffer(imgBuffer);
314d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            return OK;
315d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        }
316d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
317893068ad0ca0cce8428f5a358c86b81139399c07Zhijun He        if (imgBuffer.width != static_cast<uint32_t>(l.mParameters.previewWidth) ||
318893068ad0ca0cce8428f5a358c86b81139399c07Zhijun He                imgBuffer.height != static_cast<uint32_t>(l.mParameters.previewHeight)) {
319893068ad0ca0cce8428f5a358c86b81139399c07Zhijun He            ALOGW("%s: The preview size has changed to %d x %d from %d x %d, this buffer is"
320893068ad0ca0cce8428f5a358c86b81139399c07Zhijun He                    " no longer valid, dropping",__FUNCTION__,
321893068ad0ca0cce8428f5a358c86b81139399c07Zhijun He                    l.mParameters.previewWidth, l.mParameters.previewHeight,
322893068ad0ca0cce8428f5a358c86b81139399c07Zhijun He                    imgBuffer.width, imgBuffer.height);
323893068ad0ca0cce8428f5a358c86b81139399c07Zhijun He            mCallbackConsumer->unlockBuffer(imgBuffer);
324893068ad0ca0cce8428f5a358c86b81139399c07Zhijun He            return OK;
325893068ad0ca0cce8428f5a358c86b81139399c07Zhijun He        }
326893068ad0ca0cce8428f5a358c86b81139399c07Zhijun He
3274a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala        previewFormat = l.mParameters.previewFormat;
3284a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala        useFlexibleYuv = l.mParameters.fastInfo.useFlexibleYuv &&
3294a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala                (previewFormat == HAL_PIXEL_FORMAT_YCrCb_420_SP ||
3304a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala                 previewFormat == HAL_PIXEL_FORMAT_YV12);
3314a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala
3324a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala        int32_t expectedFormat = useFlexibleYuv ?
3334a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala                HAL_PIXEL_FORMAT_YCbCr_420_888 : previewFormat;
3344a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala
3354a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala        if (imgBuffer.format != expectedFormat) {
336d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            ALOGE("%s: Camera %d: Unexpected format for callback: "
3374a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala                    "0x%x, expected 0x%x", __FUNCTION__, mId,
3384a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala                    imgBuffer.format, expectedFormat);
339d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            mCallbackConsumer->unlockBuffer(imgBuffer);
340d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            return INVALID_OPERATION;
341d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        }
342d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
343d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        // In one-shot mode, stop sending callbacks after the first one
344d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        if (l.mParameters.previewCallbackFlags &
345d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala                CAMERA_FRAME_CALLBACK_FLAG_ONE_SHOT_MASK) {
346d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            ALOGV("%s: clearing oneshot", __FUNCTION__);
347d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            l.mParameters.previewCallbackOneShot = false;
348d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        }
349d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
350ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He        uint32_t destYStride = 0;
351ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He        uint32_t destCStride = 0;
352ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He        if (useFlexibleYuv) {
353ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He            if (previewFormat == HAL_PIXEL_FORMAT_YV12) {
354ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He                // Strides must align to 16 for YV12
355ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He                destYStride = ALIGN(imgBuffer.width, 16);
356ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He                destCStride = ALIGN(destYStride / 2, 16);
357ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He            } else {
358ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He                // No padding for NV21
359ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He                ALOG_ASSERT(previewFormat == HAL_PIXEL_FORMAT_YCrCb_420_SP,
360ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He                        "Unexpected preview format 0x%x", previewFormat);
361ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He                destYStride = imgBuffer.width;
362ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He                destCStride = destYStride / 2;
363ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He            }
3644a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala        } else {
365ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He            destYStride = imgBuffer.stride;
366ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He            // don't care about cStride
3674a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala        }
3684a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala
369ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He        size_t bufferSize = Camera2Client::calculateBufferSize(
370ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He                imgBuffer.width, imgBuffer.height,
371ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He                previewFormat, destYStride);
372ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He        size_t currentBufferSize = (mCallbackHeap == 0) ?
373ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He                0 : (mCallbackHeap->mHeap->getSize() / kCallbackHeapCount);
374ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He        if (bufferSize != currentBufferSize) {
375ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He            mCallbackHeap.clear();
376ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He            mCallbackHeap = new Camera2Heap(bufferSize, kCallbackHeapCount,
377ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He                    "Camera2Client::CallbackHeap");
378ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He            if (mCallbackHeap->mHeap->getSize() == 0) {
379ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He                ALOGE("%s: Camera %d: Unable to allocate memory for callbacks",
380ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He                        __FUNCTION__, mId);
381ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He                mCallbackConsumer->unlockBuffer(imgBuffer);
382ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He                return INVALID_OPERATION;
383ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He            }
384ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He
385ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He            mCallbackHeapHead = 0;
386ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He            mCallbackHeapFree = kCallbackHeapCount;
387ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He        }
388ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He
389ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He        if (mCallbackHeapFree == 0) {
390ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He            ALOGE("%s: Camera %d: No free callback buffers, dropping frame",
391d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala                    __FUNCTION__, mId);
392d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            mCallbackConsumer->unlockBuffer(imgBuffer);
393ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He            return OK;
394d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        }
395d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
396ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He        heapIdx = mCallbackHeapHead;
397d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
39827b0159fa29b85b63f7bcad83bd13c70355a7bcddaisuke jinno        mCallbackHeapHead = (mCallbackHeapHead + 1) % kCallbackHeapCount;
399ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He        mCallbackHeapFree--;
400d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
401ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He        // TODO: Get rid of this copy by passing the gralloc queue all the way
402ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He        // to app
403d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
404ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He        ssize_t offset;
405ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He        size_t size;
406ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He        sp<IMemoryHeap> heap =
407ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He                mCallbackHeap->mBuffers[heapIdx]->getMemory(&offset,
408ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He                        &size);
409ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He        uint8_t *data = (uint8_t*)heap->getBase() + offset;
4104a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala
411ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He        if (!useFlexibleYuv) {
412ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He            // Can just memcpy when HAL format matches API format
413ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He            memcpy(data, imgBuffer.data, bufferSize);
414ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He        } else {
415ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He            res = convertFromFlexibleYuv(previewFormat, data, imgBuffer,
416ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He                    destYStride, destCStride);
417ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He            if (res != OK) {
418ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He                ALOGE("%s: Camera %d: Can't convert between 0x%x and 0x%x formats!",
419ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He                        __FUNCTION__, mId, imgBuffer.format, previewFormat);
420ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He                mCallbackConsumer->unlockBuffer(imgBuffer);
421ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He                return BAD_VALUE;
422ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He            }
4234a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala        }
424d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
425ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He        ALOGV("%s: Freeing buffer", __FUNCTION__);
426ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He        mCallbackConsumer->unlockBuffer(imgBuffer);
427e6478de72a8ae1d3abb3e8c20898977c45354a4fEino-Ville Talvala
428e6478de72a8ae1d3abb3e8c20898977c45354a4fEino-Ville Talvala        // mCallbackHeap may get freed up once input mutex is released
429e6478de72a8ae1d3abb3e8c20898977c45354a4fEino-Ville Talvala        callbackHeap = mCallbackHeap;
430ddb104d382e5432e0b15c1b3ee91ba0eed73d0ecZhijun He    }
431d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
432d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    // Call outside parameter lock to allow re-entrancy from notification
433d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    {
43444cfcf00b9008c1c04f4c8277c6c06af039fd976Igor Murashkin        Camera2Client::SharedCameraCallbacks::Lock
43544cfcf00b9008c1c04f4c8277c6c06af039fd976Igor Murashkin            l(client->mSharedCameraCallbacks);
43644cfcf00b9008c1c04f4c8277c6c06af039fd976Igor Murashkin        if (l.mRemoteCallback != 0) {
437d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala            ALOGV("%s: Camera %d: Invoking client data callback",
438d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala                    __FUNCTION__, mId);
43944cfcf00b9008c1c04f4c8277c6c06af039fd976Igor Murashkin            l.mRemoteCallback->dataCallback(CAMERA_MSG_PREVIEW_FRAME,
440e6478de72a8ae1d3abb3e8c20898977c45354a4fEino-Ville Talvala                    callbackHeap->mBuffers[heapIdx], NULL);
441d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala        }
442d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    }
443d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
444d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    // Only increment free if we're still using the same heap
445d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    mCallbackHeapFree++;
446d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
447d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    ALOGV("%s: exit", __FUNCTION__);
448d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
449d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala    return OK;
450d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala}
451d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala
4524a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvalastatus_t CallbackProcessor::convertFromFlexibleYuv(int32_t previewFormat,
4534a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala        uint8_t *dst,
4544a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala        const CpuConsumer::LockedBuffer &src,
4554a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala        uint32_t dstYStride,
4564a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala        uint32_t dstCStride) const {
4574a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala
4584a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala    if (previewFormat != HAL_PIXEL_FORMAT_YCrCb_420_SP &&
4594a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala            previewFormat != HAL_PIXEL_FORMAT_YV12) {
4604a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala        ALOGE("%s: Camera %d: Unexpected preview format when using "
4614a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala                "flexible YUV: 0x%x", __FUNCTION__, mId, previewFormat);
4624a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala        return INVALID_OPERATION;
4634a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala    }
4644a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala
4654a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala    // Copy Y plane, adjusting for stride
4664a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala    const uint8_t *ySrc = src.data;
4674a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala    uint8_t *yDst = dst;
4684a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala    for (size_t row = 0; row < src.height; row++) {
4694a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala        memcpy(yDst, ySrc, src.width);
4704a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala        ySrc += src.stride;
4714a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala        yDst += dstYStride;
4724a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala    }
4734a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala
4744a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala    // Copy/swizzle chroma planes, 4:2:0 subsampling
4759c910c2d780ce1afa221f963da4d4a307443d9beEino-Ville Talvala    const uint8_t *cbSrc = src.dataCb;
4769c910c2d780ce1afa221f963da4d4a307443d9beEino-Ville Talvala    const uint8_t *crSrc = src.dataCr;
4774a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala    size_t chromaHeight = src.height / 2;
4784a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala    size_t chromaWidth = src.width / 2;
4794a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala    ssize_t chromaGap = src.chromaStride -
4804a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala            (chromaWidth * src.chromaStep);
4814a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala    size_t dstChromaGap = dstCStride - chromaWidth;
4824a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala
4834a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala    if (previewFormat == HAL_PIXEL_FORMAT_YCrCb_420_SP) {
4847e66ebc932b4cfa9b4611dffeeb1e91399deb442Eino-Ville Talvala        // Flexible YUV chroma to NV21 chroma
4859c910c2d780ce1afa221f963da4d4a307443d9beEino-Ville Talvala        uint8_t *crcbDst = yDst;
4867e66ebc932b4cfa9b4611dffeeb1e91399deb442Eino-Ville Talvala        // Check for shortcuts
4879c910c2d780ce1afa221f963da4d4a307443d9beEino-Ville Talvala        if (cbSrc == crSrc + 1 && src.chromaStep == 2) {
4889c910c2d780ce1afa221f963da4d4a307443d9beEino-Ville Talvala            ALOGV("%s: Fast NV21->NV21", __FUNCTION__);
4897e66ebc932b4cfa9b4611dffeeb1e91399deb442Eino-Ville Talvala            // Source has semiplanar CrCb chroma layout, can copy by rows
4907e66ebc932b4cfa9b4611dffeeb1e91399deb442Eino-Ville Talvala            for (size_t row = 0; row < chromaHeight; row++) {
4919c910c2d780ce1afa221f963da4d4a307443d9beEino-Ville Talvala                memcpy(crcbDst, crSrc, src.width);
4929c910c2d780ce1afa221f963da4d4a307443d9beEino-Ville Talvala                crcbDst += src.width;
4939c910c2d780ce1afa221f963da4d4a307443d9beEino-Ville Talvala                crSrc += src.chromaStride;
4947e66ebc932b4cfa9b4611dffeeb1e91399deb442Eino-Ville Talvala            }
4957e66ebc932b4cfa9b4611dffeeb1e91399deb442Eino-Ville Talvala        } else {
4969c910c2d780ce1afa221f963da4d4a307443d9beEino-Ville Talvala            ALOGV("%s: Generic->NV21", __FUNCTION__);
4977e66ebc932b4cfa9b4611dffeeb1e91399deb442Eino-Ville Talvala            // Generic copy, always works but not very efficient
4987e66ebc932b4cfa9b4611dffeeb1e91399deb442Eino-Ville Talvala            for (size_t row = 0; row < chromaHeight; row++) {
4997e66ebc932b4cfa9b4611dffeeb1e91399deb442Eino-Ville Talvala                for (size_t col = 0; col < chromaWidth; col++) {
5009c910c2d780ce1afa221f963da4d4a307443d9beEino-Ville Talvala                    *(crcbDst++) = *crSrc;
5019c910c2d780ce1afa221f963da4d4a307443d9beEino-Ville Talvala                    *(crcbDst++) = *cbSrc;
5029c910c2d780ce1afa221f963da4d4a307443d9beEino-Ville Talvala                    crSrc += src.chromaStep;
5039c910c2d780ce1afa221f963da4d4a307443d9beEino-Ville Talvala                    cbSrc += src.chromaStep;
5047e66ebc932b4cfa9b4611dffeeb1e91399deb442Eino-Ville Talvala                }
5059c910c2d780ce1afa221f963da4d4a307443d9beEino-Ville Talvala                crSrc += chromaGap;
5069c910c2d780ce1afa221f963da4d4a307443d9beEino-Ville Talvala                cbSrc += chromaGap;
5074a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala            }
5084a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala        }
5094a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala    } else {
5107e66ebc932b4cfa9b4611dffeeb1e91399deb442Eino-Ville Talvala        // flexible YUV chroma to YV12 chroma
5114a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala        ALOG_ASSERT(previewFormat == HAL_PIXEL_FORMAT_YV12,
5124a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala                "Unexpected preview format 0x%x", previewFormat);
5139c910c2d780ce1afa221f963da4d4a307443d9beEino-Ville Talvala        uint8_t *crDst = yDst;
5149c910c2d780ce1afa221f963da4d4a307443d9beEino-Ville Talvala        uint8_t *cbDst = yDst + chromaHeight * dstCStride;
5157e66ebc932b4cfa9b4611dffeeb1e91399deb442Eino-Ville Talvala        if (src.chromaStep == 1) {
5169c910c2d780ce1afa221f963da4d4a307443d9beEino-Ville Talvala            ALOGV("%s: Fast YV12->YV12", __FUNCTION__);
5177e66ebc932b4cfa9b4611dffeeb1e91399deb442Eino-Ville Talvala            // Source has planar chroma layout, can copy by row
5187e66ebc932b4cfa9b4611dffeeb1e91399deb442Eino-Ville Talvala            for (size_t row = 0; row < chromaHeight; row++) {
5199c910c2d780ce1afa221f963da4d4a307443d9beEino-Ville Talvala                memcpy(crDst, crSrc, chromaWidth);
5209c910c2d780ce1afa221f963da4d4a307443d9beEino-Ville Talvala                crDst += dstCStride;
5219c910c2d780ce1afa221f963da4d4a307443d9beEino-Ville Talvala                crSrc += src.chromaStride;
5227e66ebc932b4cfa9b4611dffeeb1e91399deb442Eino-Ville Talvala            }
5237e66ebc932b4cfa9b4611dffeeb1e91399deb442Eino-Ville Talvala            for (size_t row = 0; row < chromaHeight; row++) {
5249c910c2d780ce1afa221f963da4d4a307443d9beEino-Ville Talvala                memcpy(cbDst, cbSrc, chromaWidth);
5259c910c2d780ce1afa221f963da4d4a307443d9beEino-Ville Talvala                cbDst += dstCStride;
5269c910c2d780ce1afa221f963da4d4a307443d9beEino-Ville Talvala                cbSrc += src.chromaStride;
5277e66ebc932b4cfa9b4611dffeeb1e91399deb442Eino-Ville Talvala            }
5287e66ebc932b4cfa9b4611dffeeb1e91399deb442Eino-Ville Talvala        } else {
5299c910c2d780ce1afa221f963da4d4a307443d9beEino-Ville Talvala            ALOGV("%s: Generic->YV12", __FUNCTION__);
5307e66ebc932b4cfa9b4611dffeeb1e91399deb442Eino-Ville Talvala            // Generic copy, always works but not very efficient
5317e66ebc932b4cfa9b4611dffeeb1e91399deb442Eino-Ville Talvala            for (size_t row = 0; row < chromaHeight; row++) {
5327e66ebc932b4cfa9b4611dffeeb1e91399deb442Eino-Ville Talvala                for (size_t col = 0; col < chromaWidth; col++) {
5339c910c2d780ce1afa221f963da4d4a307443d9beEino-Ville Talvala                    *(crDst++) = *crSrc;
5349c910c2d780ce1afa221f963da4d4a307443d9beEino-Ville Talvala                    *(cbDst++) = *cbSrc;
5359c910c2d780ce1afa221f963da4d4a307443d9beEino-Ville Talvala                    crSrc += src.chromaStep;
5369c910c2d780ce1afa221f963da4d4a307443d9beEino-Ville Talvala                    cbSrc += src.chromaStep;
5377e66ebc932b4cfa9b4611dffeeb1e91399deb442Eino-Ville Talvala                }
5389c910c2d780ce1afa221f963da4d4a307443d9beEino-Ville Talvala                crSrc += chromaGap;
5399c910c2d780ce1afa221f963da4d4a307443d9beEino-Ville Talvala                cbSrc += chromaGap;
5409c910c2d780ce1afa221f963da4d4a307443d9beEino-Ville Talvala                crDst += dstChromaGap;
5419c910c2d780ce1afa221f963da4d4a307443d9beEino-Ville Talvala                cbDst += dstChromaGap;
5424a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala            }
5434a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala        }
5444a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala    }
5454a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala
5464a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala    return OK;
5474a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala}
5484a66ad403b21a256773c719ae39f7b5e705b244eEino-Ville Talvala
549d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala}; // namespace camera2
550d86a6880fe86bda21a9b53b240996fc410a512a5Eino-Ville Talvala}; // namespace android
551