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