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