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

Commit 90afe080 authored by Jiwen Cai's avatar Jiwen Cai Committed by Android (Google) Code Review
Browse files

Merge "Refactor AImage/AImageReader"

parents f14c49bf 2f1a4737
Loading
Loading
Loading
Loading
+9 −3
Original line number Diff line number Diff line
@@ -646,7 +646,9 @@ media_status_t AImage_getNumberOfPlanes(const AImage* image, /*out*/int32_t* num
 *         <li>{@link AMEDIA_ERROR_UNSUPPORTED} if pixel stride is undefined for the format of input
 *                 image.</li>
 *         <li>{@link AMEDIA_ERROR_INVALID_OBJECT} if the {@link AImageReader} generated this
 *                 image has been deleted.</li></ul>
 *                 image has been deleted.</li>
 *         <li>{@link AMEDIA_IMGREADER_CANNOT_LOCK_IMAGE} if the {@link AImage} cannot be locked
 *                 for CPU access.</li></ul>
 */
media_status_t AImage_getPlanePixelStride(
        const AImage* image, int planeIdx, /*out*/int32_t* pixelStride);
@@ -671,7 +673,9 @@ media_status_t AImage_getPlanePixelStride(
 *         <li>{@link AMEDIA_ERROR_UNSUPPORTED} if row stride is undefined for the format of input
 *                 image.</li>
 *         <li>{@link AMEDIA_ERROR_INVALID_OBJECT} if the {@link AImageReader} generated this
 *                 image has been deleted.</li></ul>
 *                 image has been deleted.</li>
 *         <li>{@link AMEDIA_IMGREADER_CANNOT_LOCK_IMAGE} if the {@link AImage} cannot be locked
 *                 for CPU access.</li></ul>
 */
media_status_t AImage_getPlaneRowStride(
        const AImage* image, int planeIdx, /*out*/int32_t* rowStride);
@@ -693,7 +697,9 @@ media_status_t AImage_getPlaneRowStride(
 *         <li>{@link AMEDIA_ERROR_INVALID_PARAMETER} if image, data or dataLength is NULL, or
 *                 planeIdx is out of the range of [0, numOfPlanes - 1].</li>
 *         <li>{@link AMEDIA_ERROR_INVALID_OBJECT} if the {@link AImageReader} generated this
 *                 image has been deleted.</li></ul>
 *                 image has been deleted.</li>
 *         <li>{@link AMEDIA_IMGREADER_CANNOT_LOCK_IMAGE} if the {@link AImage} cannot be locked
 *                 for CPU access.</li></ul>
 */
media_status_t AImage_getPlaneData(
        const AImage* image, int planeIdx,
+3 −0
Original line number Diff line number Diff line
@@ -60,6 +60,9 @@ typedef enum {
    AMEDIA_IMGREADER_ERROR_BASE          = -30000,
    AMEDIA_IMGREADER_NO_BUFFER_AVAILABLE = AMEDIA_IMGREADER_ERROR_BASE - 1,
    AMEDIA_IMGREADER_MAX_IMAGES_ACQUIRED = AMEDIA_IMGREADER_ERROR_BASE - 2,
    AMEDIA_IMGREADER_CANNOT_LOCK_IMAGE   = AMEDIA_IMGREADER_ERROR_BASE - 3,
    AMEDIA_IMGREADER_CANNOT_UNLOCK_IMAGE = AMEDIA_IMGREADER_ERROR_BASE - 4,
    AMEDIA_IMGREADER_IMAGE_NOT_LOCKED    = AMEDIA_IMGREADER_ERROR_BASE - 5,

} media_status_t;

+6 −1
Original line number Diff line number Diff line
@@ -34,9 +34,12 @@ LOCAL_MODULE:= libmediandk

LOCAL_C_INCLUDES := \
    bionic/libc/private \
    external/piex \
    frameworks/base/core/jni \
    frameworks/base/media/jni \
    frameworks/av/include/ndk \
    system/media/camera/include
    system/media/camera/include \
    $(call include-path-for, libhardware)/hardware \

LOCAL_CFLAGS += -fvisibility=hidden -D EXPORT='__attribute__ ((visibility ("default")))'

@@ -45,7 +48,9 @@ LOCAL_CFLAGS += -Werror -Wall
LOCAL_SHARED_LIBRARIES := \
    libbinder \
    libmedia \
    libmedia_jni \
    libmediadrm \
    libskia \
    libstagefright \
    libstagefright_foundation \
    liblog \
+201 −80
Original line number Diff line number Diff line
@@ -22,6 +22,8 @@
#include "NdkImagePriv.h"
#include "NdkImageReaderPriv.h"

#include <android_media_Utils.h>
#include <android_runtime/android_hardware_HardwareBuffer.h>
#include <utils/Log.h>
#include "hardware/camera3.h"

@@ -29,11 +31,11 @@ using namespace android;

#define ALIGN(x, mask) ( ((x) + (mask) - 1) & ~((mask) - 1) )

AImage::AImage(AImageReader* reader, int32_t format,
        CpuConsumer::LockedBuffer* buffer, int64_t timestamp,
AImage::AImage(AImageReader* reader, int32_t format, uint64_t usage,
        BufferItem* buffer, int64_t timestamp,
        int32_t width, int32_t height, int32_t numPlanes) :
        mReader(reader), mFormat(format),
        mBuffer(buffer), mTimestamp(timestamp),
        mReader(reader), mFormat(format), mUsage(usage),
        mBuffer(buffer), mLockedBuffer(nullptr), mTimestamp(timestamp),
        mWidth(width), mHeight(height), mNumPlanes(numPlanes) {
}

@@ -66,6 +68,7 @@ AImage::close() {
    // Should have been set to nullptr in releaseImageLocked
    // Set to nullptr here for extra safety only
    mBuffer = nullptr;
    mLockedBuffer = nullptr;
    mIsClosed = true;
}

@@ -169,8 +172,80 @@ AImage::getTimestamp(int64_t* timestamp) const {
    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);
        return AMEDIA_ERROR_INVALID_OBJECT;
    }

    if ((mUsage & AHARDWAREBUFFER_USAGE0_CPU_READ_OFTEN) == 0) {
        ALOGE("%s: AImage %p does not have any software read usage bits set, usage=%" PRIu64 "",
              __FUNCTION__, this, mUsage);
        return AMEDIA_IMGREADER_CANNOT_LOCK_IMAGE;
    }

    if (mLockedBuffer != nullptr) {
        // Return immediately if the image has already been locked.
        return AMEDIA_OK;
    }

    auto lockedBuffer = std::make_unique<CpuConsumer::LockedBuffer>();

    uint64_t producerUsage;
    uint64_t consumerUsage;
    android_hardware_HardwareBuffer_convertToGrallocUsageBits(
            &producerUsage, &consumerUsage, mUsage, 0);

    status_t ret =
            lockImageFromBuffer(mBuffer, consumerUsage, mBuffer->mFence->dup(), lockedBuffer.get());
    if (ret != OK) {
        ALOGE("%s: AImage %p failed to lock, error=%d", __FUNCTION__, this, ret);
        return AMEDIA_IMGREADER_CANNOT_LOCK_IMAGE;
    }

    ALOGV("%s: Successfully locked the image %p.", __FUNCTION__, this);
    mLockedBuffer = std::move(lockedBuffer);

    return AMEDIA_OK;
}

media_status_t AImage::unlockImageIfLocked(int* fenceFd) {
    if (fenceFd == nullptr) {
        LOG_ALWAYS_FATAL("%s: fenceFd cannot be null.", __FUNCTION__);
        return AMEDIA_ERROR_INVALID_PARAMETER;
    }

    if (mBuffer == nullptr || mBuffer->mGraphicBuffer == nullptr) {
        LOG_ALWAYS_FATAL("%s: AImage %p has no buffer.", __FUNCTION__, this);
        return AMEDIA_ERROR_INVALID_OBJECT;
    }

    if (mLockedBuffer == nullptr) {
        // This image hasn't been locked yet, no need to unlock.
        *fenceFd = -1;
        return AMEDIA_OK;
    }

    // No fence by default.
    int releaseFenceFd = -1;
    status_t res = mBuffer->mGraphicBuffer->unlockAsync(&releaseFenceFd);
    if (res != OK) {
        ALOGE("%s unlock buffer failed on iamge %p.", __FUNCTION__, this);
        *fenceFd = -1;
        return AMEDIA_IMGREADER_CANNOT_UNLOCK_IMAGE;
    }

    *fenceFd = releaseFenceFd;
    return AMEDIA_OK;
}

media_status_t
AImage::getPlanePixelStride(int planeIdx, /*out*/int32_t* pixelStride) const {
    if (mLockedBuffer == nullptr) {
        ALOGE("%s: buffer not locked.", __FUNCTION__);
        return AMEDIA_IMGREADER_IMAGE_NOT_LOCKED;
    }

    if (planeIdx < 0 || planeIdx >= mNumPlanes) {
        ALOGE("Error: planeIdx %d out of bound [0,%d]",
                planeIdx, mNumPlanes - 1);
@@ -183,10 +258,10 @@ AImage::getPlanePixelStride(int planeIdx, /*out*/int32_t* pixelStride) const {
        ALOGE("%s: image %p has been closed!", __FUNCTION__, this);
        return AMEDIA_ERROR_INVALID_OBJECT;
    }
    int32_t fmt = mBuffer->flexFormat;
    int32_t fmt = mLockedBuffer->flexFormat;
    switch (fmt) {
        case HAL_PIXEL_FORMAT_YCbCr_420_888:
            *pixelStride = (planeIdx == 0) ? 1 : mBuffer->chromaStep;
            *pixelStride = (planeIdx == 0) ? 1 : mLockedBuffer->chromaStep;
            return AMEDIA_OK;
        case HAL_PIXEL_FORMAT_YCrCb_420_SP:
            *pixelStride = (planeIdx == 0) ? 1 : 2;
@@ -226,6 +301,11 @@ AImage::getPlanePixelStride(int planeIdx, /*out*/int32_t* pixelStride) const {

media_status_t
AImage::getPlaneRowStride(int planeIdx, /*out*/int32_t* rowStride) const {
    if (mLockedBuffer == nullptr) {
        ALOGE("%s: buffer not locked.", __FUNCTION__);
        return AMEDIA_IMGREADER_IMAGE_NOT_LOCKED;
    }

    if (planeIdx < 0 || planeIdx >= mNumPlanes) {
        ALOGE("Error: planeIdx %d out of bound [0,%d]",
                planeIdx, mNumPlanes - 1);
@@ -238,54 +318,58 @@ AImage::getPlaneRowStride(int planeIdx, /*out*/int32_t* rowStride) const {
        ALOGE("%s: image %p has been closed!", __FUNCTION__, this);
        return AMEDIA_ERROR_INVALID_OBJECT;
    }
    int32_t fmt = mBuffer->flexFormat;
    int32_t fmt = mLockedBuffer->flexFormat;
    switch (fmt) {
        case HAL_PIXEL_FORMAT_YCbCr_420_888:
            *rowStride = (planeIdx == 0) ? mBuffer->stride : mBuffer->chromaStride;
            *rowStride = (planeIdx == 0) ? mLockedBuffer->stride
                                         : mLockedBuffer->chromaStride;
            return AMEDIA_OK;
        case HAL_PIXEL_FORMAT_YCrCb_420_SP:
            *rowStride = mBuffer->width;
            *rowStride = mLockedBuffer->width;
            return AMEDIA_OK;
        case HAL_PIXEL_FORMAT_YV12:
            if (mBuffer->stride % 16) {
                ALOGE("Stride %d is not 16 pixel aligned!", mBuffer->stride);
            if (mLockedBuffer->stride % 16) {
                ALOGE("Stride %d is not 16 pixel aligned!", mLockedBuffer->stride);
                return AMEDIA_ERROR_UNKNOWN;
            }
            *rowStride = (planeIdx == 0) ? mBuffer->stride : ALIGN(mBuffer->stride / 2, 16);
            *rowStride = (planeIdx == 0) ? mLockedBuffer->stride
                                         : ALIGN(mLockedBuffer->stride / 2, 16);
            return AMEDIA_OK;
        case HAL_PIXEL_FORMAT_RAW10:
        case HAL_PIXEL_FORMAT_RAW12:
            // RAW10 and RAW12 are used for 10-bit and 12-bit raw data, they are single plane
            *rowStride = mBuffer->stride;
            *rowStride = mLockedBuffer->stride;
            return AMEDIA_OK;
        case HAL_PIXEL_FORMAT_Y8:
            if (mBuffer->stride % 16) {
                ALOGE("Stride %d is not 16 pixel aligned!", mBuffer->stride);
            if (mLockedBuffer->stride % 16) {
                ALOGE("Stride %d is not 16 pixel aligned!",
                      mLockedBuffer->stride);
                return AMEDIA_ERROR_UNKNOWN;
            }
            *rowStride = mBuffer->stride;
            *rowStride = mLockedBuffer->stride;
            return AMEDIA_OK;
        case HAL_PIXEL_FORMAT_Y16:
        case HAL_PIXEL_FORMAT_RAW16:
            // In native side, strides are specified in pixels, not in bytes.
            // Single plane 16bpp bayer data. even width/height,
            // row stride multiple of 16 pixels (32 bytes)
            if (mBuffer->stride % 16) {
                ALOGE("Stride %d is not 16 pixel aligned!", mBuffer->stride);
            if (mLockedBuffer->stride % 16) {
                ALOGE("Stride %d is not 16 pixel aligned!",
                      mLockedBuffer->stride);
                return AMEDIA_ERROR_UNKNOWN;
            }
            *rowStride = mBuffer->stride * 2;
            *rowStride = mLockedBuffer->stride * 2;
            return AMEDIA_OK;
        case HAL_PIXEL_FORMAT_RGB_565:
            *rowStride = mBuffer->stride * 2;
            *rowStride = mLockedBuffer->stride * 2;
            return AMEDIA_OK;
        case HAL_PIXEL_FORMAT_RGBA_8888:
        case HAL_PIXEL_FORMAT_RGBX_8888:
            *rowStride = mBuffer->stride * 4;
            *rowStride = mLockedBuffer->stride * 4;
            return AMEDIA_OK;
        case HAL_PIXEL_FORMAT_RGB_888:
            // Single plane, 24bpp.
            *rowStride = mBuffer->stride * 3;
            *rowStride = mLockedBuffer->stride * 3;
            return AMEDIA_OK;
        case HAL_PIXEL_FORMAT_BLOB:
        case HAL_PIXEL_FORMAT_RAW_OPAQUE:
@@ -300,13 +384,13 @@ AImage::getPlaneRowStride(int planeIdx, /*out*/int32_t* rowStride) const {

uint32_t
AImage::getJpegSize() const {
    if (mBuffer == nullptr) {
    if (mLockedBuffer == nullptr) {
        LOG_ALWAYS_FATAL("Error: buffer is null");
    }

    uint32_t size = 0;
    uint32_t width = mBuffer->width;
    uint8_t* jpegBuffer = mBuffer->data;
    uint32_t width = mLockedBuffer->width;
    uint8_t* jpegBuffer = mLockedBuffer->data;

    // First check for JPEG transport header at the end of the buffer
    uint8_t* header = jpegBuffer + (width - sizeof(struct camera3_jpeg_blob));
@@ -334,6 +418,11 @@ AImage::getJpegSize() const {

media_status_t
AImage::getPlaneData(int planeIdx,/*out*/uint8_t** data, /*out*/int* dataLength) const {
    if (mLockedBuffer == nullptr) {
        ALOGE("%s: buffer not locked.", __FUNCTION__);
        return AMEDIA_IMGREADER_IMAGE_NOT_LOCKED;
    }

    if (planeIdx < 0 || planeIdx >= mNumPlanes) {
        ALOGE("Error: planeIdx %d out of bound [0,%d]",
                planeIdx, mNumPlanes - 1);
@@ -352,140 +441,154 @@ AImage::getPlaneData(int planeIdx,/*out*/uint8_t** data, /*out*/int* dataLength)
    uint8_t* cr = nullptr;
    uint8_t* pData = nullptr;
    int bytesPerPixel = 0;
    int32_t fmt = mBuffer->flexFormat;
    int32_t fmt = mLockedBuffer->flexFormat;

    switch (fmt) {
        case HAL_PIXEL_FORMAT_YCbCr_420_888:
            pData = (planeIdx == 0) ? mBuffer->data :
                    (planeIdx == 1) ? mBuffer->dataCb : mBuffer->dataCr;
            pData = (planeIdx == 0) ? mLockedBuffer->data
                                    : (planeIdx == 1) ? mLockedBuffer->dataCb
                                                      : mLockedBuffer->dataCr;
            // only map until last pixel
            if (planeIdx == 0) {
                dataSize = mBuffer->stride * (mBuffer->height - 1) + mBuffer->width;
                dataSize = mLockedBuffer->stride * (mLockedBuffer->height - 1) +
                           mLockedBuffer->width;
            } else {
                dataSize = mBuffer->chromaStride * (mBuffer->height / 2 - 1) +
                        mBuffer->chromaStep * (mBuffer->width / 2 - 1) + 1;
                dataSize =
                    mLockedBuffer->chromaStride *
                        (mLockedBuffer->height / 2 - 1) +
                    mLockedBuffer->chromaStep * (mLockedBuffer->width / 2 - 1) +
                    1;
            }
            break;
        // NV21
        case HAL_PIXEL_FORMAT_YCrCb_420_SP:
            cr = mBuffer->data + (mBuffer->stride * mBuffer->height);
            cr = mLockedBuffer->data +
                 (mLockedBuffer->stride * mLockedBuffer->height);
            cb = cr + 1;
            // only map until last pixel
            ySize = mBuffer->width * (mBuffer->height - 1) + mBuffer->width;
            cSize = mBuffer->width * (mBuffer->height / 2 - 1) + mBuffer->width - 1;

            pData = (planeIdx == 0) ? mBuffer->data :
                    (planeIdx == 1) ? cb : cr;
            ySize = mLockedBuffer->width * (mLockedBuffer->height - 1) +
                    mLockedBuffer->width;
            cSize = mLockedBuffer->width * (mLockedBuffer->height / 2 - 1) +
                    mLockedBuffer->width - 1;
            pData = (planeIdx == 0) ? mLockedBuffer->data
                                    : (planeIdx == 1) ? cb : cr;
            dataSize = (planeIdx == 0) ? ySize : cSize;
            break;
        case HAL_PIXEL_FORMAT_YV12:
            // Y and C stride need to be 16 pixel aligned.
            if (mBuffer->stride % 16) {
                ALOGE("Stride %d is not 16 pixel aligned!", mBuffer->stride);
            if (mLockedBuffer->stride % 16) {
                ALOGE("Stride %d is not 16 pixel aligned!",
                      mLockedBuffer->stride);
                return AMEDIA_ERROR_UNKNOWN;
            }

            ySize = mBuffer->stride * mBuffer->height;
            cStride = ALIGN(mBuffer->stride / 2, 16);
            cr = mBuffer->data + ySize;
            cSize = cStride * mBuffer->height / 2;
            ySize = mLockedBuffer->stride * mLockedBuffer->height;
            cStride = ALIGN(mLockedBuffer->stride / 2, 16);
            cr = mLockedBuffer->data + ySize;
            cSize = cStride * mLockedBuffer->height / 2;
            cb = cr + cSize;

            pData = (planeIdx == 0) ? mBuffer->data :
                    (planeIdx == 1) ? cb : cr;
            pData = (planeIdx == 0) ? mLockedBuffer->data
                                    : (planeIdx == 1) ? cb : cr;
            dataSize = (planeIdx == 0) ? ySize : cSize;
            break;
        case HAL_PIXEL_FORMAT_Y8:
            // Single plane, 8bpp.

            pData = mBuffer->data;
            dataSize = mBuffer->stride * mBuffer->height;
            pData = mLockedBuffer->data;
            dataSize = mLockedBuffer->stride * mLockedBuffer->height;
            break;
        case HAL_PIXEL_FORMAT_Y16:
            bytesPerPixel = 2;

            pData = mBuffer->data;
            dataSize = mBuffer->stride * mBuffer->height * bytesPerPixel;
            pData = mLockedBuffer->data;
            dataSize =
                mLockedBuffer->stride * mLockedBuffer->height * bytesPerPixel;
            break;
        case HAL_PIXEL_FORMAT_BLOB:
            // Used for JPEG data, height must be 1, width == size, single plane.
            if (mBuffer->height != 1) {
                ALOGE("Jpeg should have height value one but got %d", mBuffer->height);
            if (mLockedBuffer->height != 1) {
                ALOGE("Jpeg should have height value one but got %d",
                      mLockedBuffer->height);
                return AMEDIA_ERROR_UNKNOWN;
            }

            pData = mBuffer->data;
            pData = mLockedBuffer->data;
            dataSize = getJpegSize();
            break;
        case HAL_PIXEL_FORMAT_RAW16:
            // Single plane 16bpp bayer data.
            bytesPerPixel = 2;
            pData = mBuffer->data;
            dataSize = mBuffer->stride * mBuffer->height * bytesPerPixel;
            pData = mLockedBuffer->data;
            dataSize =
                mLockedBuffer->stride * mLockedBuffer->height * bytesPerPixel;
            break;
        case HAL_PIXEL_FORMAT_RAW_OPAQUE:
            // Used for RAW_OPAQUE data, height must be 1, width == size, single plane.
            if (mBuffer->height != 1) {
                ALOGE("RAW_OPAQUE should have height value one but got %d", mBuffer->height);
            if (mLockedBuffer->height != 1) {
                ALOGE("RAW_OPAQUE should have height value one but got %d",
                      mLockedBuffer->height);
                return AMEDIA_ERROR_UNKNOWN;
            }
            pData = mBuffer->data;
            dataSize = mBuffer->width;
            pData = mLockedBuffer->data;
            dataSize = mLockedBuffer->width;
            break;
        case HAL_PIXEL_FORMAT_RAW10:
            // Single plane 10bpp bayer data.
            if (mBuffer->width % 4) {
                ALOGE("Width is not multiple of 4 %d", mBuffer->width);
            if (mLockedBuffer->width % 4) {
                ALOGE("Width is not multiple of 4 %d", mLockedBuffer->width);
                return AMEDIA_ERROR_UNKNOWN;
            }
            if (mBuffer->height % 2) {
                ALOGE("Height is not multiple of 2 %d", mBuffer->height);
            if (mLockedBuffer->height % 2) {
                ALOGE("Height is not multiple of 2 %d", mLockedBuffer->height);
                return AMEDIA_ERROR_UNKNOWN;
            }
            if (mBuffer->stride < (mBuffer->width * 10 / 8)) {
            if (mLockedBuffer->stride < (mLockedBuffer->width * 10 / 8)) {
                ALOGE("stride (%d) should be at least %d",
                        mBuffer->stride, mBuffer->width * 10 / 8);
                        mLockedBuffer->stride, mLockedBuffer->width * 10 / 8);
                return AMEDIA_ERROR_UNKNOWN;
            }
            pData = mBuffer->data;
            dataSize = mBuffer->stride * mBuffer->height;
            pData = mLockedBuffer->data;
            dataSize = mLockedBuffer->stride * mLockedBuffer->height;
            break;
        case HAL_PIXEL_FORMAT_RAW12:
            // Single plane 10bpp bayer data.
            if (mBuffer->width % 4) {
                ALOGE("Width is not multiple of 4 %d", mBuffer->width);
            if (mLockedBuffer->width % 4) {
                ALOGE("Width is not multiple of 4 %d", mLockedBuffer->width);
                return AMEDIA_ERROR_UNKNOWN;
            }
            if (mBuffer->height % 2) {
                ALOGE("Height is not multiple of 2 %d", mBuffer->height);
            if (mLockedBuffer->height % 2) {
                ALOGE("Height is not multiple of 2 %d", mLockedBuffer->height);
                return AMEDIA_ERROR_UNKNOWN;
            }
            if (mBuffer->stride < (mBuffer->width * 12 / 8)) {
            if (mLockedBuffer->stride < (mLockedBuffer->width * 12 / 8)) {
                ALOGE("stride (%d) should be at least %d",
                        mBuffer->stride, mBuffer->width * 12 / 8);
                        mLockedBuffer->stride, mLockedBuffer->width * 12 / 8);
                return AMEDIA_ERROR_UNKNOWN;
            }
            pData = mBuffer->data;
            dataSize = mBuffer->stride * mBuffer->height;
            pData = mLockedBuffer->data;
            dataSize = mLockedBuffer->stride * mLockedBuffer->height;
            break;
        case HAL_PIXEL_FORMAT_RGBA_8888:
        case HAL_PIXEL_FORMAT_RGBX_8888:
            // Single plane, 32bpp.
            bytesPerPixel = 4;
            pData = mBuffer->data;
            dataSize = mBuffer->stride * mBuffer->height * bytesPerPixel;
            pData = mLockedBuffer->data;
            dataSize =
                mLockedBuffer->stride * mLockedBuffer->height * bytesPerPixel;
            break;
        case HAL_PIXEL_FORMAT_RGB_565:
            // Single plane, 16bpp.
            bytesPerPixel = 2;
            pData = mBuffer->data;
            dataSize = mBuffer->stride * mBuffer->height * bytesPerPixel;
            pData = mLockedBuffer->data;
            dataSize =
                mLockedBuffer->stride * mLockedBuffer->height * bytesPerPixel;
            break;
        case HAL_PIXEL_FORMAT_RGB_888:
            // Single plane, 24bpp.
            bytesPerPixel = 3;
            pData = mBuffer->data;
            dataSize = mBuffer->stride * mBuffer->height * bytesPerPixel;
            pData = mLockedBuffer->data;
            dataSize = mLockedBuffer->stride * mLockedBuffer->height * bytesPerPixel;
            break;
        default:
            ALOGE("Pixel format: 0x%x is unsupported", fmt);
@@ -602,6 +705,12 @@ media_status_t AImage_getPlanePixelStride(
                __FUNCTION__, image, pixelStride);
        return AMEDIA_ERROR_INVALID_PARAMETER;
    }
    media_status_t ret = const_cast<AImage*>(image)->lockImage();
    if (ret != AMEDIA_OK) {
        ALOGE("%s: failed to lock buffer for CPU access. image %p, error=%d.",
              __FUNCTION__, image, ret);
        return ret;
    }
    return image->getPlanePixelStride(planeIdx, pixelStride);
}

@@ -614,6 +723,12 @@ media_status_t AImage_getPlaneRowStride(
                __FUNCTION__, image, rowStride);
        return AMEDIA_ERROR_INVALID_PARAMETER;
    }
    media_status_t ret = const_cast<AImage*>(image)->lockImage();
    if (ret != AMEDIA_OK) {
        ALOGE("%s: failed to lock buffer for CPU access. image %p, error=%d.",
              __FUNCTION__, image, ret);
        return ret;
    }
    return image->getPlaneRowStride(planeIdx, rowStride);
}

@@ -627,5 +742,11 @@ media_status_t AImage_getPlaneData(
                __FUNCTION__, image, data, dataLength);
        return AMEDIA_ERROR_INVALID_PARAMETER;
    }
    media_status_t ret = const_cast<AImage*>(image)->lockImage();
    if (ret != AMEDIA_OK) {
        ALOGE("%s: failed to lock buffer for CPU access. image %p, error=%d.",
              __FUNCTION__, image, ret);
        return ret;
    }
    return image->getPlaneData(planeIdx, data, dataLength);
}
+10 −4
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@
#include <utils/Log.h>
#include <utils/StrongPointer.h>

#include <gui/BufferItem.h>
#include <gui/CpuConsumer.h>

#include "NdkImageReaderPriv.h"
@@ -31,8 +32,8 @@ using namespace android;

// TODO: this only supports ImageReader
struct AImage {
    AImage(AImageReader* reader, int32_t format,
            CpuConsumer::LockedBuffer* buffer, int64_t timestamp,
    AImage(AImageReader* reader, int32_t format, uint64_t usage,
           BufferItem* buffer, int64_t timestamp,
           int32_t width, int32_t height, int32_t numPlanes);

    // free all resources while keeping object alive. Caller must obtain reader lock
@@ -54,6 +55,9 @@ struct AImage {
    media_status_t getNumPlanes(/*out*/int32_t* numPlanes) const;
    media_status_t getTimestamp(/*out*/int64_t* timestamp) const;

    media_status_t lockImage();
    media_status_t unlockImageIfLocked(/*out*/int* fenceFd);

    media_status_t getPlanePixelStride(int planeIdx, /*out*/int32_t* pixelStride) const;
    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;
@@ -69,7 +73,9 @@ struct AImage {
    // When reader is close, AImage will only accept close API call
    wp<AImageReader>           mReader;
    const int32_t              mFormat;
    CpuConsumer::LockedBuffer* mBuffer;
    const uint64_t             mUsage;  // AHARDWAREBUFFER_USAGE0* flags.
    BufferItem*                mBuffer;
    std::unique_ptr<CpuConsumer::LockedBuffer> mLockedBuffer;
    const int64_t              mTimestamp;
    const int32_t              mWidth;
    const int32_t              mHeight;
Loading