Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit da6ca847 authored by Sally Qi's avatar Sally Qi
Browse files

Update AImageReader NDK due to ImageReader class change.

- align Image and ImageWriter NDK with SDK. Add another constructor to
  pass hardwareBufferFormat and dataSpace
- fix some typos in the documentations

Bug: 214045472
Bug: 224565065
Test: android.media.misc.cts.NativeImageReaderTest
Change-Id: I85ceb6132ffb4aa2d733b9b50b27c7924512fdcc
parent 059aa2d7
Loading
Loading
Loading
Loading
+29 −0
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@

#include <android_media_Utils.h>
#include <private/android/AHardwareBufferHelpers.h>
#include <ui/PublicFormat.h>
#include <utils/Log.h>
#include "hardware/camera3.h"

@@ -35,6 +36,8 @@ AImage::AImage(AImageReader* reader, int32_t format, uint64_t usage, BufferItem*
        int64_t timestamp, int32_t width, int32_t height, int32_t numPlanes) :
        mReader(reader), mFormat(format), mUsage(usage), mBuffer(buffer), mLockedBuffer(nullptr),
        mTimestamp(timestamp), mWidth(width), mHeight(height), mNumPlanes(numPlanes) {
    PublicFormat publicFormat = static_cast<PublicFormat>(format);
    mHalDataSpace = mapPublicFormatToHalDataspace(publicFormat);
    LOG_FATAL_IF(reader == nullptr, "AImageReader shouldn't be null while creating AImage");
}

@@ -157,6 +160,20 @@ AImage::getTimestamp(int64_t* timestamp) const {
    return AMEDIA_OK;
}

media_status_t
AImage::getDataSpace(android_dataspace* dataSpace) const {
    if (dataSpace == nullptr) {
        return AMEDIA_ERROR_INVALID_PARAMETER;
    }
    *dataSpace = static_cast<android_dataspace>(-1);
    if (isClosed()) {
        ALOGE("%s: image %p has been closed!", __FUNCTION__, this);
        return AMEDIA_ERROR_INVALID_OBJECT;
    }
    *dataSpace = mHalDataSpace;
    return AMEDIA_OK;
}

media_status_t AImage::lockImage() {
    if (mBuffer == nullptr || mBuffer->mGraphicBuffer == nullptr) {
        LOG_ALWAYS_FATAL("%s: AImage %p has no buffer.", __FUNCTION__, this);
@@ -763,3 +780,15 @@ media_status_t AImage_getHardwareBuffer(
    }
    return image->getHardwareBuffer(buffer);
}

EXPORT
media_status_t AImage_getDataSpace(
    const AImage* image, /*out*/int32_t* dataSpace) {
    ALOGV("%s", __FUNCTION__);

    if (image == nullptr || dataSpace == nullptr) {
        ALOGE("%s: bad argument. image %p dataSpace %p", __FUNCTION__, image, dataSpace);
        return AMEDIA_ERROR_INVALID_PARAMETER;
    }
    return image->getDataSpace((android_dataspace*)(dataSpace));
}
 No newline at end of file
+2 −0
Original line number Diff line number Diff line
@@ -82,6 +82,7 @@ struct AImage {
    media_status_t getPlaneRowStride(int planeIdx, /*out*/int32_t* rowStride) const;
    media_status_t getPlaneData(int planeIdx,/*out*/uint8_t** data, /*out*/int* dataLength) const;
    media_status_t getHardwareBuffer(/*out*/AHardwareBuffer** buffer) const;
    media_status_t getDataSpace(/*out*/android_dataspace* dataSpace) const;

  private:
    // AImage should be deleted through free() API.
@@ -101,6 +102,7 @@ struct AImage {
    const int32_t              mWidth;
    const int32_t              mHeight;
    const int32_t              mNumPlanes;
    android_dataspace          mHalDataSpace = HAL_DATASPACE_UNKNOWN;
    bool                       mIsClosed = false;
    mutable Mutex              mLock;
};
+61 −32
Original line number Diff line number Diff line
@@ -46,6 +46,9 @@ const char* AImageReader::kGraphicBufferKey = "GraphicBuffer";

static constexpr int kWindowHalTokenSizeMax = 256;

static media_status_t validateParameters(int32_t width, int32_t height, int32_t format,
                                         uint64_t usage, int32_t maxImages,
                                         /*out*/ AImageReader**& reader);
static native_handle_t *convertHalTokenToNativeHandle(const HalToken &halToken);

bool
@@ -263,13 +266,17 @@ AImageReader::AImageReader(int32_t width,
                           int32_t height,
                           int32_t format,
                           uint64_t usage,
                           int32_t maxImages)
                           int32_t maxImages,
                           uint32_t hardwareBufferFormat,
                           android_dataspace dataSpace)
    : mWidth(width),
      mHeight(height),
      mFormat(format),
      mUsage(usage),
      mMaxImages(maxImages),
      mNumPlanes(getNumPlanesForFormat(format)),
      mHalFormat(hardwareBufferFormat),
      mHalDataSpace(dataSpace),
      mFrameListener(new FrameListener(this)),
      mBufferRemovedListener(new BufferRemovedListener(this)) {}

@@ -280,9 +287,6 @@ AImageReader::~AImageReader() {

media_status_t
AImageReader::init() {
    PublicFormat publicFormat = static_cast<PublicFormat>(mFormat);
    mHalFormat = mapPublicFormatToHalFormat(publicFormat);
    mHalDataSpace = mapPublicFormatToHalDataspace(publicFormat);
    mHalUsage = AHardwareBuffer_convertToGrallocUsageBits(mUsage);

    sp<IGraphicBufferProducer> gbProducer;
@@ -646,6 +650,41 @@ AImageReader::acquireLatestImage(/*out*/AImage** image, /*out*/int* acquireFence
    }
}

static
media_status_t validateParameters(int32_t width, int32_t height, int32_t format,
                                  uint64_t usage, int32_t maxImages,
                                  /*out*/ AImageReader**& reader) {
    if (reader == nullptr) {
        ALOGE("%s: reader argument is null", __FUNCTION__);
        return AMEDIA_ERROR_INVALID_PARAMETER;
    }

    if (width < 1 || height < 1) {
        ALOGE("%s: image dimension must be positive: w:%d h:%d",
                __FUNCTION__, width, height);
        return AMEDIA_ERROR_INVALID_PARAMETER;
    }

    if (maxImages < 1) {
        ALOGE("%s: max outstanding image count must be at least 1 (%d)",
                __FUNCTION__, maxImages);
        return AMEDIA_ERROR_INVALID_PARAMETER;
    }

    if (maxImages > BufferQueueDefs::NUM_BUFFER_SLOTS) {
        ALOGE("%s: max outstanding image count (%d) cannot be larget than %d.",
              __FUNCTION__, maxImages, BufferQueueDefs::NUM_BUFFER_SLOTS);
        return AMEDIA_ERROR_INVALID_PARAMETER;
    }

    if (!AImageReader::isSupportedFormatAndUsage(format, usage)) {
        ALOGE("%s: format %d is not supported with usage 0x%" PRIx64 " by AImageReader",
                __FUNCTION__, format, usage);
        return AMEDIA_ERROR_INVALID_PARAMETER;
    }
    return AMEDIA_OK;
}

static native_handle_t *convertHalTokenToNativeHandle(
        const HalToken &halToken) {
    // We attempt to store halToken in the ints of the native_handle_t after its
@@ -696,42 +735,32 @@ media_status_t AImageReader_getWindowNativeHandle(
} //extern "C"

EXPORT
media_status_t AImageReader_newWithUsage(
        int32_t width, int32_t height, int32_t format, uint64_t usage,
        int32_t maxImages, /*out*/ AImageReader** reader) {
media_status_t AImageReader_newWithDataSpace(
        int32_t width, int32_t height, uint64_t usage, int32_t maxImages,
        uint32_t hardwareBufferFormat, int32_t dataSpace,
        /*out*/ AImageReader** reader) {
    ALOGV("%s", __FUNCTION__);

    if (width < 1 || height < 1) {
        ALOGE("%s: image dimension must be positive: w:%d h:%d",
                __FUNCTION__, width, height);
        return AMEDIA_ERROR_INVALID_PARAMETER;
    }

    if (maxImages < 1) {
        ALOGE("%s: max outstanding image count must be at least 1 (%d)",
                __FUNCTION__, maxImages);
        return AMEDIA_ERROR_INVALID_PARAMETER;
    android_dataspace halDataSpace = static_cast<android_dataspace>(dataSpace);
    int32_t format = static_cast<int32_t>(
          mapHalFormatDataspaceToPublicFormat(hardwareBufferFormat, halDataSpace));
    return AImageReader_newWithUsage(width, height, format, usage, maxImages, reader);
}

    if (maxImages > BufferQueueDefs::NUM_BUFFER_SLOTS) {
        ALOGE("%s: max outstanding image count (%d) cannot be larget than %d.",
              __FUNCTION__, maxImages, BufferQueueDefs::NUM_BUFFER_SLOTS);
        return AMEDIA_ERROR_INVALID_PARAMETER;
    }
EXPORT
media_status_t AImageReader_newWithUsage(
        int32_t width, int32_t height, int32_t format, uint64_t usage,
        int32_t maxImages, /*out*/ AImageReader** reader) {
    ALOGV("%s", __FUNCTION__);

    if (!AImageReader::isSupportedFormatAndUsage(format, usage)) {
        ALOGE("%s: format %d is not supported with usage 0x%" PRIx64 " by AImageReader",
                __FUNCTION__, format, usage);
        return AMEDIA_ERROR_INVALID_PARAMETER;
    }
    validateParameters(width, height, format, usage, maxImages, reader);

    if (reader == nullptr) {
        ALOGE("%s: reader argument is null", __FUNCTION__);
        return AMEDIA_ERROR_INVALID_PARAMETER;
    }
    PublicFormat publicFormat = static_cast<PublicFormat>(format);
    uint32_t halFormat = mapPublicFormatToHalFormat(publicFormat);
    android_dataspace halDataSpace = mapPublicFormatToHalDataspace(publicFormat);

    AImageReader* tmpReader = new AImageReader(
        width, height, format, usage, maxImages);
        width, height, format, usage, maxImages, halFormat, halDataSpace);
    if (tmpReader == nullptr) {
        ALOGE("%s: AImageReader allocation failed", __FUNCTION__);
        return AMEDIA_ERROR_UNKNOWN;
+8 −6
Original line number Diff line number Diff line
@@ -56,10 +56,12 @@ struct AImageReader : public RefBase {
                 int32_t height,
                 int32_t format,
                 uint64_t usage,
                 int32_t maxImages);
                 int32_t maxImages,
                 uint32_t hardwareBufferFormat,
                 android_dataspace dataSpace);
    ~AImageReader();

    // Inintialize AImageReader, uninitialized or failed to initialize AImageReader
    // Initialize AImageReader, uninitialized or failed to initialize AImageReader
    // should never be passed to application
    media_status_t init();

@@ -79,7 +81,6 @@ struct AImageReader : public RefBase {
    void           close();

  private:

    friend struct AImage; // for grabing reader lock

    BufferItem* getBufferItemLocked();
@@ -118,13 +119,16 @@ struct AImageReader : public RefBase {

    const int32_t mWidth;
    const int32_t mHeight;
    const int32_t mFormat;
    int32_t mFormat;
    const uint64_t mUsage;  // AHARDWAREBUFFER_USAGE_* flags.
    const int32_t mMaxImages;

    // TODO(jwcai) Seems completely unused in AImageReader class.
    const int32_t mNumPlanes;

    uint32_t mHalFormat = AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM;
    android_dataspace mHalDataSpace = HAL_DATASPACE_UNKNOWN;

    struct FrameListener : public ConsumerBase::FrameAvailableListener {
      public:
        explicit FrameListener(AImageReader* parent) : mReader(parent) {}
@@ -155,8 +159,6 @@ struct AImageReader : public RefBase {
    };
    sp<BufferRemovedListener> mBufferRemovedListener;

    int mHalFormat;
    android_dataspace mHalDataSpace;
    uint64_t mHalUsage;

    sp<IGraphicBufferProducer> mProducer;
+29 −10
Original line number Diff line number Diff line
@@ -583,7 +583,7 @@ void AImage_delete(AImage* image) __INTRODUCED_IN(24);
 * Available since API level 24.
 *
 * @param image the {@link AImage} of interest.
 * @param width the width of the image will be filled here if the method call succeeeds.
 * @param width the width of the image will be filled here if the method call succeeds.
 *
 * @return <ul>
 *         <li>{@link AMEDIA_OK} if the method call succeeds.</li>
@@ -599,7 +599,7 @@ media_status_t AImage_getWidth(const AImage* image, /*out*/int32_t* width) __INT
 * Available since API level 24.
 *
 * @param image the {@link AImage} of interest.
 * @param height the height of the image will be filled here if the method call succeeeds.
 * @param height the height of the image will be filled here if the method call succeeds.
 *
 * @return <ul>
 *         <li>{@link AMEDIA_OK} if the method call succeeds.</li>
@@ -617,7 +617,7 @@ media_status_t AImage_getHeight(const AImage* image, /*out*/int32_t* height) __I
 * Available since API level 24.
 *
 * @param image the {@link AImage} of interest.
 * @param format the format of the image will be filled here if the method call succeeeds.
 * @param format the format of the image will be filled here if the method call succeeds.
 *
 * @return <ul>
 *         <li>{@link AMEDIA_OK} if the method call succeeds.</li>
@@ -636,7 +636,7 @@ media_status_t AImage_getFormat(const AImage* image, /*out*/int32_t* format) __I
 * Available since API level 24.
 *
 * @param image the {@link AImage} of interest.
 * @param rect the cropped rectangle of the image will be filled here if the method call succeeeds.
 * @param rect the cropped rectangle of the image will be filled here if the method call succeeds.
 *
 * @return <ul>
 *         <li>{@link AMEDIA_OK} if the method call succeeds.</li>
@@ -662,7 +662,7 @@ media_status_t AImage_getCropRect(const AImage* image, /*out*/AImageCropRect* re
 * Available since API level 24.
 *
 * @param image the {@link AImage} of interest.
 * @param timestampNs the timestamp of the image will be filled here if the method call succeeeds.
 * @param timestampNs the timestamp of the image will be filled here if the method call succeeds.
 *
 * @return <ul>
 *         <li>{@link AMEDIA_OK} if the method call succeeds.</li>
@@ -682,7 +682,7 @@ media_status_t AImage_getTimestamp(const AImage* image, /*out*/int64_t* timestam
 *
 * @param image the {@link AImage} of interest.
 * @param numPlanes the number of planes of the image will be filled here if the method call
 *         succeeeds.
 *         succeeds.
 *
 * @return <ul>
 *         <li>{@link AMEDIA_OK} if the method call succeeds.</li>
@@ -706,7 +706,7 @@ media_status_t AImage_getNumberOfPlanes(const AImage* image, /*out*/int32_t* num
 *
 * @param image the {@link AImage} of interest.
 * @param planeIdx the index of the plane. Must be less than the number of planes of input image.
 * @param pixelStride the pixel stride of the image will be filled here if the method call succeeeds.
 * @param pixelStride the pixel stride of the image will be filled here if the method call succeeds.
 *
 * @return <ul>
 *         <li>{@link AMEDIA_OK} if the method call succeeds.</li>
@@ -735,7 +735,7 @@ media_status_t AImage_getPlanePixelStride(
 *
 * @param image the {@link AImage} of interest.
 * @param planeIdx the index of the plane. Must be less than the number of planes of input image.
 * @param rowStride the row stride of the image will be filled here if the method call succeeeds.
 * @param rowStride the row stride of the image will be filled here if the method call succeeds.
 *
 * @return <ul>
 *         <li>{@link AMEDIA_OK} if the method call succeeds.</li>
@@ -762,8 +762,8 @@ media_status_t AImage_getPlaneRowStride(
 *
 * @param image the {@link AImage} of interest.
 * @param planeIdx the index of the plane. Must be less than the number of planes of input image.
 * @param data the data pointer of the image will be filled here if the method call succeeeds.
 * @param dataLength the valid length of data will be filled here if the method call succeeeds.
 * @param data the data pointer of the image will be filled here if the method call succeeds.
 * @param dataLength the valid length of data will be filled here if the method call succeeds.
 *
 * @return <ul>
 *         <li>{@link AMEDIA_OK} if the method call succeeds.</li>
@@ -826,6 +826,25 @@ void AImage_deleteAsync(AImage* image, int releaseFenceFd) __INTRODUCED_IN(26);
 */
media_status_t AImage_getHardwareBuffer(const AImage* image, /*out*/AHardwareBuffer** buffer) __INTRODUCED_IN(26);

/**
 * Query the dataspace of the input {@link AImage}.
 *
 * Available since API level 33.
 *
 * @param image the {@link AImage} of interest.
 * @param dataSpace the dataspace of the image will be filled here if the method call succeeds.
 *                  This must be one of the ADATASPACE_* enum value defined in
 *                  {@link ADataSpace}.
 *
 * @return <ul>
 *         <li>{@link AMEDIA_OK} if the method call succeeds.</li>
 *         <li>{@link AMEDIA_ERROR_INVALID_PARAMETER} if image or dataSpace is NULL.</li>
 *         <li>{@link AMEDIA_ERROR_INVALID_OBJECT} if the {@link AImageReader} generated this
 *                 image has been deleted.</li></ul>
 */
media_status_t AImage_getDataSpace(const AImage* image,
                                   /*out*/int32_t* dataSpace) __INTRODUCED_IN(33);

__END_DECLS

#endif //_NDK_IMAGE_H
Loading