1c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh/* 2c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh * Copyright (C) 2016 The Android Open Source Project 3c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh * 4c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh * Licensed under the Apache License, Version 2.0 (the "License"); 5c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh * you may not use this file except in compliance with the License. 6c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh * You may obtain a copy of the License at 7c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh * 8c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh * http://www.apache.org/licenses/LICENSE-2.0 9c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh * 10c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh * Unless required by applicable law or agreed to in writing, software 11c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh * distributed under the License is distributed on an "AS IS" BASIS, 12c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh * See the License for the specific language governing permissions and 14c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh * limitations under the License. 15c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh */ 16c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh 17c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh#include <inttypes.h> 18c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh 19c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh//#define LOG_NDEBUG 0 20c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh#define LOG_TAG "NdkImageReader" 21c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh 22c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh#include "NdkImagePriv.h" 23c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh#include "NdkImageReaderPriv.h" 24c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh 25c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh#include <utils/Log.h> 26c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh#include <android_runtime/android_view_Surface.h> 27c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh 28c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yehusing namespace android; 29c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh 30c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yehnamespace { 31c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh // Get an ID that's unique within this process. 32c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh static int32_t createProcessUniqueId() { 33c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh static volatile int32_t globalCounter = 0; 34c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh return android_atomic_inc(&globalCounter); 35c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh } 36c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh} 37c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh 38c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yehconst char* AImageReader::kCallbackFpKey = "Callback"; 39c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yehconst char* AImageReader::kContextKey = "Context"; 40c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh 41c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yehbool 42c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia YehAImageReader::isSupportedFormat(int32_t format) { 43c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh switch (format) { 44c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh case AIMAGE_FORMAT_YUV_420_888: 45c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh case AIMAGE_FORMAT_JPEG: 46c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh case AIMAGE_FORMAT_RAW16: 47c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh case AIMAGE_FORMAT_RAW_PRIVATE: 48c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh case AIMAGE_FORMAT_RAW10: 49c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh case AIMAGE_FORMAT_RAW12: 50c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh case AIMAGE_FORMAT_DEPTH16: 51c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh case AIMAGE_FORMAT_DEPTH_POINT_CLOUD: 52c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh return true; 53c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh default: 54c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh return false; 55c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh } 56c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh} 57c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh 58c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yehint 59c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia YehAImageReader::getNumPlanesForFormat(int32_t format) { 60c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh switch (format) { 61c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh case AIMAGE_FORMAT_YUV_420_888: 62c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh return 3; 63c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh case AIMAGE_FORMAT_JPEG: 64c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh case AIMAGE_FORMAT_RAW16: 65c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh case AIMAGE_FORMAT_RAW_PRIVATE: 66c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh case AIMAGE_FORMAT_RAW10: 67c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh case AIMAGE_FORMAT_RAW12: 68c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh case AIMAGE_FORMAT_DEPTH16: 69c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh case AIMAGE_FORMAT_DEPTH_POINT_CLOUD: 70c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh return 1; 71c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh default: 72c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh return -1; 73c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh } 74c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh} 75c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh 76c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yehvoid 77c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia YehAImageReader::FrameListener::onFrameAvailable(const BufferItem& /*item*/) { 78c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh Mutex::Autolock _l(mLock); 79c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh sp<AImageReader> reader = mReader.promote(); 80c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh if (reader == nullptr) { 81c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh ALOGW("A frame is available after AImageReader closed!"); 82c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh return; // reader has been closed 83c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh } 84c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh if (mListener.onImageAvailable == nullptr) { 85c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh return; // No callback registered 86c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh } 87c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh 88c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh sp<AMessage> msg = new AMessage(AImageReader::kWhatImageAvailable, reader->mHandler); 89c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh msg->setPointer(AImageReader::kCallbackFpKey, (void *) mListener.onImageAvailable); 90c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh msg->setPointer(AImageReader::kContextKey, mListener.context); 91c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh msg->post(); 92c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh} 93c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh 94c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yehmedia_status_t 95c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia YehAImageReader::FrameListener::setImageListener(AImageReader_ImageListener* listener) { 96c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh Mutex::Autolock _l(mLock); 97c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh if (listener == nullptr) { 981d0955cb5257a59f0ae435fefe26c05af4f4fbb6Yin-Chia Yeh mListener.context = nullptr; 991d0955cb5257a59f0ae435fefe26c05af4f4fbb6Yin-Chia Yeh mListener.onImageAvailable = nullptr; 1001d0955cb5257a59f0ae435fefe26c05af4f4fbb6Yin-Chia Yeh } else { 1011d0955cb5257a59f0ae435fefe26c05af4f4fbb6Yin-Chia Yeh mListener = *listener; 102c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh } 103c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh return AMEDIA_OK; 104c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh} 105c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh 106c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yehmedia_status_t 107c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia YehAImageReader::setImageListenerLocked(AImageReader_ImageListener* listener) { 108c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh return mFrameListener->setImageListener(listener); 109c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh} 110c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh 111c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yehmedia_status_t 112c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia YehAImageReader::setImageListener(AImageReader_ImageListener* listener) { 113c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh Mutex::Autolock _l(mLock); 114c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh return setImageListenerLocked(listener); 115c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh} 116c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh 117c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yehvoid AImageReader::CallbackHandler::onMessageReceived( 118c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh const sp<AMessage> &msg) { 119c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh switch (msg->what()) { 120c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh case kWhatImageAvailable: 121c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh { 122c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh AImageReader_ImageCallback onImageAvailable; 123c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh void* context; 124c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh bool found = msg->findPointer(kCallbackFpKey, (void**) &onImageAvailable); 125c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh if (!found || onImageAvailable == nullptr) { 126c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh ALOGE("%s: Cannot find onImageAvailable callback fp!", __FUNCTION__); 127c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh return; 128c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh } 129c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh found = msg->findPointer(kContextKey, &context); 130c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh if (!found) { 131c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh ALOGE("%s: Cannot find callback context!", __FUNCTION__); 132c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh return; 133c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh } 134c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh (*onImageAvailable)(context, mReader); 135c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh break; 136c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh } 137c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh default: 138c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh ALOGE("%s: unknown message type %d", __FUNCTION__, msg->what()); 139c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh break; 140c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh } 141c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh} 142c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh 143c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia YehAImageReader::AImageReader(int32_t width, int32_t height, int32_t format, int32_t maxImages) : 144c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh mWidth(width), mHeight(height), mFormat(format), mMaxImages(maxImages), 145c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh mNumPlanes(getNumPlanesForFormat(format)), 146c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh mFrameListener(new FrameListener(this)) {} 147c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh 148c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yehmedia_status_t 149c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia YehAImageReader::init() { 150c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh PublicFormat publicFormat = static_cast<PublicFormat>(mFormat); 151c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh mHalFormat = android_view_Surface_mapPublicFormatToHalFormat(publicFormat); 152c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh mHalDataSpace = android_view_Surface_mapPublicFormatToHalDataspace(publicFormat); 153c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh 154c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh sp<IGraphicBufferProducer> gbProducer; 155c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh sp<IGraphicBufferConsumer> gbConsumer; 156c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh BufferQueue::createBufferQueue(&gbProducer, &gbConsumer); 157c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh 158c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh sp<CpuConsumer> cpuConsumer; 159c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh String8 consumerName = String8::format("ImageReader-%dx%df%xm%d-%d-%d", 160c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh mWidth, mHeight, mFormat, mMaxImages, getpid(), 161c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh createProcessUniqueId()); 162c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh 163c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh cpuConsumer = new CpuConsumer(gbConsumer, mMaxImages, /*controlledByApp*/true); 164c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh if (cpuConsumer == nullptr) { 165c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh ALOGE("Failed to allocate CpuConsumer"); 166c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh return AMEDIA_ERROR_UNKNOWN; 167c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh } 168c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh 169c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh mCpuConsumer = cpuConsumer; 170c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh mCpuConsumer->setName(consumerName); 171c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh mProducer = gbProducer; 172c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh 173c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh sp<ConsumerBase> consumer = cpuConsumer; 174c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh consumer->setFrameAvailableListener(mFrameListener); 175c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh 176c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh status_t res; 177c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh res = cpuConsumer->setDefaultBufferSize(mWidth, mHeight); 178c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh if (res != OK) { 179c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh ALOGE("Failed to set CpuConsumer buffer size"); 180c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh return AMEDIA_ERROR_UNKNOWN; 181c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh } 182c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh res = cpuConsumer->setDefaultBufferFormat(mHalFormat); 183c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh if (res != OK) { 184c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh ALOGE("Failed to set CpuConsumer buffer format"); 185c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh return AMEDIA_ERROR_UNKNOWN; 186c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh } 187c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh res = cpuConsumer->setDefaultBufferDataSpace(mHalDataSpace); 188c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh if (res != OK) { 189c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh ALOGE("Failed to set CpuConsumer buffer dataSpace"); 190c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh return AMEDIA_ERROR_UNKNOWN; 191c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh } 192c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh 193c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh mSurface = new Surface(mProducer, /*controlledByApp*/true); 194c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh if (mSurface == nullptr) { 195c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh ALOGE("Failed to create surface"); 196c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh return AMEDIA_ERROR_UNKNOWN; 197c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh } 198c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh mWindow = static_cast<ANativeWindow*>(mSurface.get()); 199c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh 200c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh for (int i = 0; i < mMaxImages; i++) { 201c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh CpuConsumer::LockedBuffer* buffer = new CpuConsumer::LockedBuffer; 202c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh mBuffers.push_back(buffer); 203c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh } 204c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh 205c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh mCbLooper = new ALooper; 206c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh mCbLooper->setName(consumerName.string()); 207214c833fcde68833691cc54d2a4cd995d7eb0e16Aurimas Liutikas res = mCbLooper->start( 208c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh /*runOnCallingThread*/false, 209c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh /*canCallJava*/ true, 210c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh PRIORITY_DEFAULT); 211214c833fcde68833691cc54d2a4cd995d7eb0e16Aurimas Liutikas if (res != OK) { 212214c833fcde68833691cc54d2a4cd995d7eb0e16Aurimas Liutikas ALOGE("Failed to start the looper"); 213214c833fcde68833691cc54d2a4cd995d7eb0e16Aurimas Liutikas return AMEDIA_ERROR_UNKNOWN; 214214c833fcde68833691cc54d2a4cd995d7eb0e16Aurimas Liutikas } 215c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh mHandler = new CallbackHandler(this); 216c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh mCbLooper->registerHandler(mHandler); 217c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh 218c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh return AMEDIA_OK; 219c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh} 220c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh 221c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia YehAImageReader::~AImageReader() { 222c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh Mutex::Autolock _l(mLock); 223c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh AImageReader_ImageListener nullListener = {nullptr, nullptr}; 224c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh setImageListenerLocked(&nullListener); 225c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh 226c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh if (mCbLooper != nullptr) { 227c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh mCbLooper->unregisterHandler(mHandler->id()); 228c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh mCbLooper->stop(); 229c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh } 230c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh mCbLooper.clear(); 231c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh mHandler.clear(); 232c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh 233c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh // Close all previously acquired images 234c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh for (auto it = mAcquiredImages.begin(); 235c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh it != mAcquiredImages.end(); it++) { 236c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh AImage* image = *it; 237c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh image->close(); 238c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh } 239c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh 240c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh // Delete LockedBuffers 241c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh for (auto it = mBuffers.begin(); 242c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh it != mBuffers.end(); it++) { 243c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh delete *it; 244c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh } 245c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh 246c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh if (mCpuConsumer != nullptr) { 247c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh mCpuConsumer->abandon(); 248c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh mCpuConsumer->setFrameAvailableListener(nullptr); 249c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh } 250c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh} 251c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh 252c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yehmedia_status_t 253c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia YehAImageReader::acquireCpuConsumerImageLocked(/*out*/AImage** image) { 254c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh *image = nullptr; 255c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh CpuConsumer::LockedBuffer* buffer = getLockedBufferLocked(); 256c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh if (buffer == nullptr) { 257c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh ALOGW("Unable to acquire a lockedBuffer, very likely client tries to lock more than" 258c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh " maxImages buffers"); 259c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh return AMEDIA_IMGREADER_MAX_IMAGES_ACQUIRED; 260c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh } 261c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh 262c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh status_t res = mCpuConsumer->lockNextBuffer(buffer); 263c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh if (res != NO_ERROR) { 264c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh returnLockedBufferLocked(buffer); 265c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh if (res != BAD_VALUE /*no buffers*/) { 266c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh if (res == NOT_ENOUGH_DATA) { 267c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh return AMEDIA_IMGREADER_MAX_IMAGES_ACQUIRED; 268c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh } else { 269c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh ALOGE("%s Fail to lockNextBuffer with error: %d ", 270c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh __FUNCTION__, res); 271c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh return AMEDIA_ERROR_UNKNOWN; 272c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh } 273c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh } 274c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh return AMEDIA_IMGREADER_NO_BUFFER_AVAILABLE; 275c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh } 276c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh 277c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh if (buffer->flexFormat == HAL_PIXEL_FORMAT_YCrCb_420_SP) { 278c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh ALOGE("NV21 format is not supported by AImageReader"); 279c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh return AMEDIA_ERROR_UNSUPPORTED; 280c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh } 281c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh 282c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh // Check if the left-top corner of the crop rect is origin, we currently assume this point is 283c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh // zero, will revist this once this assumption turns out problematic. 284c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh Point lt = buffer->crop.leftTop(); 285c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh if (lt.x != 0 || lt.y != 0) { 286c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh ALOGE("crop left top corner [%d, %d] need to be at origin", lt.x, lt.y); 287c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh return AMEDIA_ERROR_UNKNOWN; 288c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh } 289c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh 290c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh // Check if the producer buffer configurations match what ImageReader configured. 291c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh int outputWidth = getBufferWidth(buffer); 292c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh int outputHeight = getBufferHeight(buffer); 293c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh 294c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh int readerFmt = mHalFormat; 295c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh int readerWidth = mWidth; 296c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh int readerHeight = mHeight; 297c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh 298c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh if ((buffer->format != HAL_PIXEL_FORMAT_BLOB) && (readerFmt != HAL_PIXEL_FORMAT_BLOB) && 299c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh (readerWidth != outputWidth || readerHeight != outputHeight)) { 300c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh ALOGW("%s: Producer buffer size: %dx%d, doesn't match AImageReader configured size: %dx%d", 301c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh __FUNCTION__, outputWidth, outputHeight, readerWidth, readerHeight); 302c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh } 303c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh 304c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh int bufFmt = buffer->format; 305c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh if (readerFmt == HAL_PIXEL_FORMAT_YCbCr_420_888) { 306c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh bufFmt = buffer->flexFormat; 307c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh } 308c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh 309c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh if (readerFmt != bufFmt) { 310c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh if (readerFmt == HAL_PIXEL_FORMAT_YCbCr_420_888 && (bufFmt == 311c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh HAL_PIXEL_FORMAT_YCrCb_420_SP || bufFmt == HAL_PIXEL_FORMAT_YV12)) { 312c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh // Special casing for when producer switches to a format compatible with flexible YUV 313c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh // (HAL_PIXEL_FORMAT_YCbCr_420_888). 314c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh mHalFormat = bufFmt; 315c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh ALOGD("%s: Overriding buffer format YUV_420_888 to %x.", __FUNCTION__, bufFmt); 316c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh } else { 317c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh // Return the buffer to the queue. 318c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh mCpuConsumer->unlockBuffer(*buffer); 319c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh returnLockedBufferLocked(buffer); 320c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh 321c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh ALOGE("Producer output buffer format: 0x%x, ImageReader configured format: 0x%x", 322c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh buffer->format, readerFmt); 323c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh 324c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh return AMEDIA_ERROR_UNKNOWN; 325c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh } 326c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh } 327c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh 328c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh if (mHalFormat == HAL_PIXEL_FORMAT_BLOB) { 329c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh *image = new AImage(this, mFormat, buffer, buffer->timestamp, 330c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh readerWidth, readerHeight, mNumPlanes); 331c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh } else { 332c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh *image = new AImage(this, mFormat, buffer, buffer->timestamp, 333c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh outputWidth, outputHeight, mNumPlanes); 334c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh } 335c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh mAcquiredImages.push_back(*image); 336c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh return AMEDIA_OK; 337c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh} 338c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh 339c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia YehCpuConsumer::LockedBuffer* 340c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia YehAImageReader::getLockedBufferLocked() { 341c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh if (mBuffers.empty()) { 342c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh return nullptr; 343c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh } 344c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh // Return a LockedBuffer pointer and remove it from the list 345c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh auto it = mBuffers.begin(); 346c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh CpuConsumer::LockedBuffer* buffer = *it; 347c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh mBuffers.erase(it); 348c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh return buffer; 349c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh} 350c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh 351c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yehvoid 352c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia YehAImageReader::returnLockedBufferLocked(CpuConsumer::LockedBuffer* buffer) { 353c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh mBuffers.push_back(buffer); 354c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh} 355c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh 356c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yehvoid 357c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia YehAImageReader::releaseImageLocked(AImage* image) { 358c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh CpuConsumer::LockedBuffer* buffer = image->mBuffer; 359c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh if (buffer == nullptr) { 360c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh // This should not happen, but is not fatal 361c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh ALOGW("AImage %p has no buffer!", image); 362c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh return; 363c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh } 364c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh 365c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh mCpuConsumer->unlockBuffer(*buffer); 366c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh returnLockedBufferLocked(buffer); 367c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh image->mBuffer = nullptr; 368c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh 369c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh bool found = false; 370c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh // cleanup acquired image list 371c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh for (auto it = mAcquiredImages.begin(); 372c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh it != mAcquiredImages.end(); it++) { 373c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh AImage* readerCopy = *it; 374c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh if (readerCopy == image) { 375c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh found = true; 376c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh mAcquiredImages.erase(it); 377c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh break; 378c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh } 379c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh } 380c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh if (!found) { 381c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh ALOGE("Error: AImage %p is not generated by AImageReader %p", 382c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh image, this); 383c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh } 384c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh} 385c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh 386c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yehint 387c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia YehAImageReader::getBufferWidth(CpuConsumer::LockedBuffer* buffer) { 388c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh if (buffer == nullptr) return -1; 389c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh 390c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh if (!buffer->crop.isEmpty()) { 391c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh return buffer->crop.getWidth(); 392c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh } 393c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh return buffer->width; 394c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh} 395c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh 396c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yehint 397c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia YehAImageReader::getBufferHeight(CpuConsumer::LockedBuffer* buffer) { 398c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh if (buffer == nullptr) return -1; 399c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh 400c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh if (!buffer->crop.isEmpty()) { 401c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh return buffer->crop.getHeight(); 402c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh } 403c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh return buffer->height; 404c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh} 405c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh 406c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yehmedia_status_t 407c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia YehAImageReader::acquireNextImage(/*out*/AImage** image) { 408c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh Mutex::Autolock _l(mLock); 409c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh return acquireCpuConsumerImageLocked(image); 410c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh} 411c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh 412c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yehmedia_status_t 413c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia YehAImageReader::acquireLatestImage(/*out*/AImage** image) { 414c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh if (image == nullptr) { 415c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh return AMEDIA_ERROR_INVALID_PARAMETER; 416c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh } 417c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh Mutex::Autolock _l(mLock); 418c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh *image = nullptr; 419c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh AImage* prevImage = nullptr; 420c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh AImage* nextImage = nullptr; 421c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh media_status_t ret = acquireCpuConsumerImageLocked(&prevImage); 422c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh if (prevImage == nullptr) { 423c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh return ret; 424c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh } 425c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh for (;;) { 426c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh ret = acquireCpuConsumerImageLocked(&nextImage); 427c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh if (nextImage == nullptr) { 428c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh *image = prevImage; 429c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh return AMEDIA_OK; 430c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh } 431c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh prevImage->close(); 432c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh prevImage->free(); 433c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh prevImage = nextImage; 434c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh nextImage = nullptr; 435c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh } 436c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh} 437c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh 438c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia YehEXPORT 439c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yehmedia_status_t AImageReader_new( 440c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh int32_t width, int32_t height, int32_t format, int32_t maxImages, 441c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh /*out*/AImageReader** reader) { 442c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh ALOGV("%s", __FUNCTION__); 443c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh 444c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh if (width < 1 || height < 1) { 445c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh ALOGE("%s: image dimension must be positive: w:%d h:%d", 446c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh __FUNCTION__, width, height); 447c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh return AMEDIA_ERROR_INVALID_PARAMETER; 448c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh } 449c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh 450c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh if (maxImages < 1) { 451c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh ALOGE("%s: max outstanding image count must be at least 1 (%d)", 452c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh __FUNCTION__, maxImages); 453c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh return AMEDIA_ERROR_INVALID_PARAMETER; 454c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh } 455c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh 456c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh if (!AImageReader::isSupportedFormat(format)) { 457c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh ALOGE("%s: format %d is not supported by AImageReader", 458c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh __FUNCTION__, format); 459c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh return AMEDIA_ERROR_INVALID_PARAMETER; 460c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh } 461c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh 462c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh if (reader == nullptr) { 463c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh ALOGE("%s: reader argument is null", __FUNCTION__); 464c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh return AMEDIA_ERROR_INVALID_PARAMETER; 465c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh } 466c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh 467c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh //*reader = new AImageReader(width, height, format, maxImages); 468c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh AImageReader* tmpReader = new AImageReader(width, height, format, maxImages); 469c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh if (tmpReader == nullptr) { 470c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh ALOGE("%s: AImageReader allocation failed", __FUNCTION__); 471c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh return AMEDIA_ERROR_UNKNOWN; 472c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh } 473c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh media_status_t ret = tmpReader->init(); 474c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh if (ret != AMEDIA_OK) { 475c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh ALOGE("%s: AImageReader initialization failed!", __FUNCTION__); 476c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh delete tmpReader; 477c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh return ret; 478c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh } 479c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh *reader = tmpReader; 480c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh (*reader)->incStrong((void*) AImageReader_new); 481c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh return AMEDIA_OK; 482c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh} 483c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh 484c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia YehEXPORT 485c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yehvoid AImageReader_delete(AImageReader* reader) { 486c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh ALOGV("%s", __FUNCTION__); 487c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh if (reader != nullptr) { 488c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh reader->decStrong((void*) AImageReader_delete); 489c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh } 490c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh return; 491c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh} 492c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh 493c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia YehEXPORT 494c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yehmedia_status_t AImageReader_getWindow(AImageReader* reader, /*out*/ANativeWindow** window) { 495c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh ALOGE("%s", __FUNCTION__); 496c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh if (reader == nullptr || window == nullptr) { 497c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh ALOGE("%s: invalid argument. reader %p, window %p", 498c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh __FUNCTION__, reader, window); 499c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh return AMEDIA_ERROR_INVALID_PARAMETER; 500c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh } 501c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh *window = reader->getWindow(); 502c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh return AMEDIA_OK; 503c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh} 504c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh 505c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia YehEXPORT 506c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yehmedia_status_t AImageReader_getWidth(const AImageReader* reader, /*out*/int32_t* width) { 507c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh ALOGV("%s", __FUNCTION__); 508c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh if (reader == nullptr || width == nullptr) { 509c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh ALOGE("%s: invalid argument. reader %p, width %p", 510c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh __FUNCTION__, reader, width); 511c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh return AMEDIA_ERROR_INVALID_PARAMETER; 512c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh } 513c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh *width = reader->getWidth(); 514c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh return AMEDIA_OK; 515c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh} 516c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh 517c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia YehEXPORT 518c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yehmedia_status_t AImageReader_getHeight(const AImageReader* reader, /*out*/int32_t* height) { 519c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh ALOGV("%s", __FUNCTION__); 520c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh if (reader == nullptr || height == nullptr) { 521c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh ALOGE("%s: invalid argument. reader %p, height %p", 522c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh __FUNCTION__, reader, height); 523c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh return AMEDIA_ERROR_INVALID_PARAMETER; 524c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh } 525c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh *height = reader->getHeight(); 526c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh return AMEDIA_OK; 527c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh} 528c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh 529c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia YehEXPORT 530c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yehmedia_status_t AImageReader_getFormat(const AImageReader* reader, /*out*/int32_t* format) { 531c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh ALOGV("%s", __FUNCTION__); 532c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh if (reader == nullptr || format == nullptr) { 533c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh ALOGE("%s: invalid argument. reader %p, format %p", 534c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh __FUNCTION__, reader, format); 535c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh return AMEDIA_ERROR_INVALID_PARAMETER; 536c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh } 537c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh *format = reader->getFormat(); 538c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh return AMEDIA_OK; 539c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh} 540c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh 541c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia YehEXPORT 542c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yehmedia_status_t AImageReader_getMaxImages(const AImageReader* reader, /*out*/int32_t* maxImages) { 543c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh ALOGV("%s", __FUNCTION__); 544c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh if (reader == nullptr || maxImages == nullptr) { 545c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh ALOGE("%s: invalid argument. reader %p, maxImages %p", 546c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh __FUNCTION__, reader, maxImages); 547c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh return AMEDIA_ERROR_INVALID_PARAMETER; 548c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh } 549c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh *maxImages = reader->getMaxImages(); 550c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh return AMEDIA_OK; 551c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh} 552c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh 553c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia YehEXPORT 554c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yehmedia_status_t AImageReader_acquireNextImage(AImageReader* reader, /*out*/AImage** image) { 555c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh ALOGV("%s", __FUNCTION__); 556c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh if (reader == nullptr || image == nullptr) { 557c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh ALOGE("%s: invalid argument. reader %p, maxImages %p", 558c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh __FUNCTION__, reader, image); 559c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh return AMEDIA_ERROR_INVALID_PARAMETER; 560c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh } 561c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh return reader->acquireNextImage(image); 562c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh} 563c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh 564c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia YehEXPORT 565c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yehmedia_status_t AImageReader_acquireLatestImage(AImageReader* reader, /*out*/AImage** image) { 566c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh ALOGV("%s", __FUNCTION__); 567c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh if (reader == nullptr || image == nullptr) { 568c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh ALOGE("%s: invalid argument. reader %p, maxImages %p", 569c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh __FUNCTION__, reader, image); 570c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh return AMEDIA_ERROR_INVALID_PARAMETER; 571c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh } 572c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh return reader->acquireLatestImage(image); 573c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh} 574c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh 575c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia YehEXPORT 576c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yehmedia_status_t AImageReader_setImageListener( 577c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh AImageReader* reader, AImageReader_ImageListener* listener) { 578c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh ALOGV("%s", __FUNCTION__); 5791d0955cb5257a59f0ae435fefe26c05af4f4fbb6Yin-Chia Yeh if (reader == nullptr) { 5801d0955cb5257a59f0ae435fefe26c05af4f4fbb6Yin-Chia Yeh ALOGE("%s: invalid argument! reader %p", __FUNCTION__, reader); 581c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh return AMEDIA_ERROR_INVALID_PARAMETER; 582c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh } 583c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh 584c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh reader->setImageListener(listener); 585c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh return AMEDIA_OK; 586c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh} 587