1 /*
2 * Copyright 2018 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *
16 */
17
18 #define LOG_TAG "ImageReaderTestHelpers"
19
20 #include "ImageReaderTestHelpers.h"
21
22 #include <android/log.h>
23
24 #define ALOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)
25 #define ALOGW(...) __android_log_print(ANDROID_LOG_WARN, LOG_TAG, __VA_ARGS__)
26 #define ALOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)
27
ImageReaderHelper(int32_t width,int32_t height,int32_t format,uint64_t usage,int32_t maxImages)28 ImageReaderHelper::ImageReaderHelper(int32_t width, int32_t height,
29 int32_t format, uint64_t usage,
30 int32_t maxImages)
31 : mWidth(width), mHeight(height), mFormat(format), mUsage(usage),
32 mMaxImages(maxImages) {}
33
~ImageReaderHelper()34 ImageReaderHelper::~ImageReaderHelper() {
35 mAcquiredImage.reset();
36 if (mImgReaderAnw) {
37 AImageReader_delete(mImgReader);
38 // No need to call ANativeWindow_release on imageReaderAnw
39 }
40 }
41
initImageReader()42 int ImageReaderHelper::initImageReader() {
43 if (mImgReader != nullptr || mImgReaderAnw != nullptr) {
44 ALOGE("Cannot re-initalize image reader, mImgReader=%p, mImgReaderAnw=%p",
45 mImgReader, mImgReaderAnw);
46 return -1;
47 }
48
49 int ret = AImageReader_newWithUsage(mWidth, mHeight, mFormat, mUsage,
50 mMaxImages, &mImgReader);
51 if (ret != AMEDIA_OK || mImgReader == nullptr) {
52 ALOGE("Failed to create new AImageReader, ret=%d, mImgReader=%p", ret,
53 mImgReader);
54 return -1;
55 }
56
57 ret = AImageReader_setImageListener(mImgReader, &mReaderAvailableCb);
58 if (ret != AMEDIA_OK) {
59 ALOGE("Failed to set image available listener, ret=%d.", ret);
60 return ret;
61 }
62
63 ret = AImageReader_getWindow(mImgReader, &mImgReaderAnw);
64 if (ret != AMEDIA_OK || mImgReaderAnw == nullptr) {
65 ALOGE("Failed to get ANativeWindow from AImageReader, ret=%d, "
66 "mImgReaderAnw=%p.",
67 ret, mImgReaderAnw);
68 return -1;
69 }
70
71 return 0;
72 }
73
getBufferFromCurrentImage(AHardwareBuffer ** outBuffer)74 int ImageReaderHelper::getBufferFromCurrentImage(AHardwareBuffer **outBuffer) {
75 std::lock_guard<std::mutex> lock(mMutex);
76
77 int ret = 0;
78 if (mAvailableImages > 0) {
79 AImage *outImage = nullptr;
80
81 mAvailableImages -= 1;
82
83 ret = AImageReader_acquireNextImage(mImgReader, &outImage);
84 if (ret != AMEDIA_OK || outImage == nullptr) {
85 // When the BufferQueue is in async mode, it is still possible that
86 // AImageReader_acquireNextImage returns nothing after onFrameAvailable.
87 ALOGW("Failed to acquire image, ret=%d, outIamge=%p.", ret, outImage);
88 } else {
89 // Any exisitng in mAcquiredImage will be deleted and released
90 // automatically.
91 mAcquiredImage.reset(outImage);
92 }
93 }
94
95 if (mAcquiredImage == nullptr) {
96 return -EAGAIN;
97 }
98
99 // Note that AImage_getHardwareBuffer is not acquiring additional reference to
100 // the buffer, so we can return it here any times we want without worrying
101 // about releasing.
102 AHardwareBuffer *buffer = nullptr;
103 ret = AImage_getHardwareBuffer(mAcquiredImage.get(), &buffer);
104 if (ret != AMEDIA_OK || buffer == nullptr) {
105 ALOGE("Faild to get hardware buffer, ret=%d, outBuffer=%p.", ret, buffer);
106 return -ENOMEM;
107 }
108
109 *outBuffer = buffer;
110 return 0;
111 }
112
handleImageAvailable()113 void ImageReaderHelper::handleImageAvailable() {
114 std::lock_guard<std::mutex> lock(mMutex);
115
116 mAvailableImages += 1;
117 }
118
onImageAvailable(void * obj,AImageReader *)119 void ImageReaderHelper::onImageAvailable(void *obj, AImageReader *) {
120 ImageReaderHelper *thiz = reinterpret_cast<ImageReaderHelper *>(obj);
121 thiz->handleImageAvailable();
122 }
123