Home | History | Annotate | Download | only in jni
      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