Implementing new NdkImageReader APIs
Bug: 35114769
Test: Build (should have no functional change from headers change), and
run CTS test CtsNativeImageReaderTestCases on a Pixel.
Change-Id: Icb40196363d9f10a5d853c17f0bc378b6c27b3f6
diff --git a/media/ndk/NdkImage.cpp b/media/ndk/NdkImage.cpp
index 6c9a644..95fdf36 100644
--- a/media/ndk/NdkImage.cpp
+++ b/media/ndk/NdkImage.cpp
@@ -31,10 +31,10 @@
#define ALIGN(x, mask) ( ((x) + (mask) - 1) & ~((mask) - 1) )
-AImage::AImage(AImageReader* reader, int32_t format, uint64_t usage,
+AImage::AImage(AImageReader* reader, int32_t format, uint64_t usage0, uint64_t usage1,
BufferItem* buffer, int64_t timestamp,
int32_t width, int32_t height, int32_t numPlanes) :
- mReader(reader), mFormat(format), mUsage(usage),
+ mReader(reader), mFormat(format), mUsage0(usage0), mUsage1(usage1),
mBuffer(buffer), mLockedBuffer(nullptr), mTimestamp(timestamp),
mWidth(width), mHeight(height), mNumPlanes(numPlanes) {
}
@@ -54,7 +54,7 @@
}
void
-AImage::close() {
+AImage::close(int releaseFenceFd) {
Mutex::Autolock _l(mLock);
if (mIsClosed) {
return;
@@ -64,7 +64,7 @@
LOG_ALWAYS_FATAL("Error: AImage not closed before AImageReader close!");
return;
}
- reader->releaseImageLocked(this);
+ reader->releaseImageLocked(this, releaseFenceFd);
// Should have been set to nullptr in releaseImageLocked
// Set to nullptr here for extra safety only
mBuffer = nullptr;
@@ -178,9 +178,9 @@
return AMEDIA_ERROR_INVALID_OBJECT;
}
- if ((mUsage & AHARDWAREBUFFER_USAGE0_CPU_READ_OFTEN) == 0) {
+ if ((mUsage0 & AHARDWAREBUFFER_USAGE0_CPU_READ_OFTEN) == 0) {
ALOGE("%s: AImage %p does not have any software read usage bits set, usage=%" PRIu64 "",
- __FUNCTION__, this, mUsage);
+ __FUNCTION__, this, mUsage0);
return AMEDIA_IMGREADER_CANNOT_LOCK_IMAGE;
}
@@ -194,7 +194,7 @@
uint64_t producerUsage;
uint64_t consumerUsage;
android_hardware_HardwareBuffer_convertToGrallocUsageBits(
- &producerUsage, &consumerUsage, mUsage, 0);
+ &producerUsage, &consumerUsage, mUsage0, mUsage1);
status_t ret =
lockImageFromBuffer(mBuffer, consumerUsage, mBuffer->mFence->dup(), lockedBuffer.get());
@@ -600,12 +600,31 @@
return AMEDIA_OK;
}
+media_status_t
+AImage::getHardwareBuffer(/*out*/AHardwareBuffer** buffer) const {
+ if (mBuffer == nullptr || mBuffer->mGraphicBuffer == nullptr) {
+ ALOGE("%s: AImage %p has no buffer.", __FUNCTION__, this);
+ return AMEDIA_ERROR_INVALID_OBJECT;
+ }
+
+ // TODO(jwcai) Someone from Android graphics team stating this should just be a static_cast.
+ *buffer = reinterpret_cast<AHardwareBuffer*>(mBuffer->mGraphicBuffer.get());
+ return AMEDIA_OK;
+}
+
EXPORT
void AImage_delete(AImage* image) {
ALOGV("%s", __FUNCTION__);
+ AImage_deleteAsync(image, -1);
+ return;
+}
+
+EXPORT
+void AImage_deleteAsync(AImage* image, int releaseFenceFd) {
+ ALOGV("%s", __FUNCTION__);
if (image != nullptr) {
image->lockReader();
- image->close();
+ image->close(releaseFenceFd);
image->unlockReader();
if (!image->isClosed()) {
LOG_ALWAYS_FATAL("Image close failed!");
@@ -750,3 +769,15 @@
}
return image->getPlaneData(planeIdx, data, dataLength);
}
+
+EXPORT
+media_status_t AImage_getHardwareBuffer(
+ const AImage* image, /*out*/AHardwareBuffer** buffer) {
+ ALOGV("%s", __FUNCTION__);
+
+ if (image == nullptr || buffer == nullptr) {
+ ALOGE("%s: bad argument. image %p buffer %p", __FUNCTION__, image, buffer);
+ return AMEDIA_ERROR_INVALID_PARAMETER;
+ }
+ return image->getHardwareBuffer(buffer);
+}