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 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 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 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 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 113 void ImageReaderHelper::handleImageAvailable() { 114 std::lock_guard<std::mutex> lock(mMutex); 115 116 mAvailableImages += 1; 117 } 118 119 void ImageReaderHelper::onImageAvailable(void *obj, AImageReader *) { 120 ImageReaderHelper *thiz = reinterpret_cast<ImageReaderHelper *>(obj); 121 thiz->handleImageAvailable(); 122 } 123