Fix ImageWriter builder pattern APIs
- fix getFormat() mismatch by fix the way of reading dataspace value in
the android_media_ImageWriter#Image_getFormat function.
- fix getDataSpace() mismatch when the Image is dequeued from
ImageWriter.
- skip usage bit setup if image format is opaque.
Bug: 215717202
Bug: 215718355
Test: android.hardware.cts.DataSpaceTest,android.hardware.camera2.cts.ImageWriterTest,android.hardware.camera2.cts.ImageReaderTest
Change-Id: I375739322c3fdad2dc23be3558f4bd8cd396d8b6
diff --git a/media/jni/android_media_ImageWriter.cpp b/media/jni/android_media_ImageWriter.cpp
index 2e419a6..eca26dc 100644
--- a/media/jni/android_media_ImageWriter.cpp
+++ b/media/jni/android_media_ImageWriter.cpp
@@ -460,8 +460,6 @@
} else {
// Set consumer buffer format to user specified format
android_dataspace nativeDataspace = static_cast<android_dataspace>(dataSpace);
- int userFormat = static_cast<int>(mapHalFormatDataspaceToPublicFormat(
- hardwareBufferFormat, nativeDataspace));
res = native_window_set_buffers_format(anw.get(), hardwareBufferFormat);
if (res != OK) {
ALOGE("%s: Unable to configure consumer native buffer format to %#x",
@@ -478,20 +476,29 @@
return 0;
}
ctx->setBufferDataSpace(nativeDataspace);
- surfaceFormat = userFormat;
+ surfaceFormat = static_cast<int32_t>(mapHalFormatDataspaceToPublicFormat(
+ hardwareBufferFormat, nativeDataspace));
}
ctx->setBufferFormat(surfaceFormat);
env->SetIntField(thiz,
gImageWriterClassInfo.mWriterFormat, reinterpret_cast<jint>(surfaceFormat));
- res = native_window_set_usage(anw.get(), ndkUsage);
- if (res != OK) {
- ALOGE("%s: Configure usage %08x for format %08x failed: %s (%d)",
- __FUNCTION__, static_cast<unsigned int>(ndkUsage),
- surfaceFormat, strerror(-res), res);
- jniThrowRuntimeException(env, "Failed to SW_WRITE_OFTEN configure usage");
- return 0;
+ // ndkUsage == -1 means setUsage in ImageWriter class is not called.
+ // skip usage setting if setUsage in ImageWriter is not called and imageformat is opaque.
+ if (!(ndkUsage == -1 && isFormatOpaque(surfaceFormat))) {
+ if (ndkUsage == -1) {
+ ndkUsage = GRALLOC_USAGE_SW_WRITE_OFTEN;
+ }
+ res = native_window_set_usage(anw.get(), ndkUsage);
+ if (res != OK) {
+ ALOGE("%s: Configure usage %08x for format %08x failed: %s (%d)",
+ __FUNCTION__, static_cast<unsigned int>(ndkUsage),
+ surfaceFormat, strerror(-res), res);
+ jniThrowRuntimeException(env,
+ "Failed to SW_WRITE_OFTEN configure usage");
+ return 0;
+ }
}
int minUndequeuedBufferCount = 0;
@@ -952,7 +959,7 @@
return buffer->getHeight();
}
-static jint Image_getFormat(JNIEnv* env, jobject thiz) {
+static jint Image_getFormat(JNIEnv* env, jobject thiz, jlong dataSpace) {
ALOGV("%s", __FUNCTION__);
GraphicBuffer* buffer;
Image_getNativeContext(env, thiz, &buffer, NULL);
@@ -962,9 +969,9 @@
return 0;
}
- // ImageWriter doesn't support data space yet, assuming it is unknown.
PublicFormat publicFmt = mapHalFormatDataspaceToPublicFormat(buffer->getPixelFormat(),
- HAL_DATASPACE_UNKNOWN);
+ static_cast<android_dataspace>(dataSpace));
+
return static_cast<jint>(publicFmt);
}
@@ -1031,14 +1038,14 @@
}
static jobjectArray Image_createSurfacePlanes(JNIEnv* env, jobject thiz,
- int numPlanes, int writerFormat) {
+ int numPlanes, int writerFormat, long dataSpace) {
ALOGV("%s: create SurfacePlane array with size %d", __FUNCTION__, numPlanes);
int rowStride, pixelStride;
uint8_t *pData;
uint32_t dataSize;
jobject byteBuffer;
- int format = Image_getFormat(env, thiz);
+ int format = Image_getFormat(env, thiz, dataSpace);
if (isFormatOpaque(format) && numPlanes > 0) {
String8 msg;
msg.appendFormat("Format 0x%x is opaque, thus not writable, the number of planes (%d)"
@@ -1108,11 +1115,11 @@
};
static JNINativeMethod gImageMethods[] = {
- {"nativeCreatePlanes", "(II)[Landroid/media/ImageWriter$WriterSurfaceImage$SurfacePlane;",
+ {"nativeCreatePlanes", "(IIJ)[Landroid/media/ImageWriter$WriterSurfaceImage$SurfacePlane;",
(void*)Image_createSurfacePlanes },
{"nativeGetWidth", "()I", (void*)Image_getWidth },
{"nativeGetHeight", "()I", (void*)Image_getHeight },
- {"nativeGetFormat", "()I", (void*)Image_getFormat },
+ {"nativeGetFormat", "(J)I", (void*)Image_getFormat },
{"nativeGetHardwareBuffer", "()Landroid/hardware/HardwareBuffer;",
(void*)Image_getHardwareBuffer },
};