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