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