Merge "Fix cts flaky issue on adt3 device."

This commit is contained in:
Sally Qi
2022-12-07 18:29:09 +00:00
committed by Gerrit Code Review
4 changed files with 99 additions and 133 deletions

View File

@@ -277,7 +277,7 @@ public class ImageReader implements AutoCloseable {
} }
private void initializeImageReader(int width, int height, int imageFormat, int maxImages, private void initializeImageReader(int width, int height, int imageFormat, int maxImages,
long usage, int hardwareBufferFormat, int dataSpace, boolean useLegacyImageFormat) { long usage, int hardwareBufferFormat, int dataSpace) {
if (width < 1 || height < 1) { if (width < 1 || height < 1) {
throw new IllegalArgumentException( throw new IllegalArgumentException(
"The image dimensions must be positive"); "The image dimensions must be positive");
@@ -306,8 +306,7 @@ public class ImageReader implements AutoCloseable {
// complex, and 1 buffer is enough for the VM to treat the ImageReader as being of some // complex, and 1 buffer is enough for the VM to treat the ImageReader as being of some
// size. // size.
mEstimatedNativeAllocBytes = ImageUtils.getEstimatedNativeAllocBytes( mEstimatedNativeAllocBytes = ImageUtils.getEstimatedNativeAllocBytes(
width, height, useLegacyImageFormat ? imageFormat : hardwareBufferFormat, width, height, imageFormat, /*buffer count*/ 1);
/*buffer count*/ 1);
VMRuntime.getRuntime().registerNativeAllocation(mEstimatedNativeAllocBytes); VMRuntime.getRuntime().registerNativeAllocation(mEstimatedNativeAllocBytes);
} }
@@ -322,28 +321,26 @@ public class ImageReader implements AutoCloseable {
// retrieve hal Format and hal dataspace from imageFormat // retrieve hal Format and hal dataspace from imageFormat
mHardwareBufferFormat = PublicFormatUtils.getHalFormat(mFormat); mHardwareBufferFormat = PublicFormatUtils.getHalFormat(mFormat);
mDataSpace = PublicFormatUtils.getHalDataspace(mFormat); mDataSpace = PublicFormatUtils.getHalDataspace(mFormat);
mUseLegacyImageFormat = true;
mNumPlanes = ImageUtils.getNumPlanesForFormat(mFormat); mNumPlanes = ImageUtils.getNumPlanesForFormat(mFormat);
initializeImageReader(width, height, imageFormat, maxImages, usage, mHardwareBufferFormat, initializeImageReader(width, height, imageFormat, maxImages, usage, mHardwareBufferFormat,
mDataSpace, mUseLegacyImageFormat); mDataSpace);
} }
private ImageReader(int width, int height, int maxImages, long usage, private ImageReader(int width, int height, int maxImages, long usage,
MultiResolutionImageReader parent, int hardwareBufferFormat, int dataSpace) { MultiResolutionImageReader parent, int hardwareBufferFormat, int dataSpace) {
mWidth = width; mWidth = width;
mHeight = height; mHeight = height;
mFormat = ImageFormat.UNKNOWN; // set default image format value as UNKNOWN
mUsage = usage; mUsage = usage;
mMaxImages = maxImages; mMaxImages = maxImages;
mParent = parent; mParent = parent;
mHardwareBufferFormat = hardwareBufferFormat; mHardwareBufferFormat = hardwareBufferFormat;
mDataSpace = dataSpace; mDataSpace = dataSpace;
mUseLegacyImageFormat = false;
mNumPlanes = ImageUtils.getNumPlanesForHardwareBufferFormat(mHardwareBufferFormat); mNumPlanes = ImageUtils.getNumPlanesForHardwareBufferFormat(mHardwareBufferFormat);
mFormat = PublicFormatUtils.getPublicFormat(hardwareBufferFormat, dataSpace);
initializeImageReader(width, height, mFormat, maxImages, usage, hardwareBufferFormat, initializeImageReader(width, height, mFormat, maxImages, usage, hardwareBufferFormat,
dataSpace, mUseLegacyImageFormat); dataSpace);
} }
/** /**
@@ -537,12 +534,7 @@ public class ImageReader implements AutoCloseable {
* @hide * @hide
*/ */
public Image acquireNextImageNoThrowISE() { public Image acquireNextImageNoThrowISE() {
SurfaceImage si; SurfaceImage si = new SurfaceImage(mFormat);
if (mUseLegacyImageFormat) {
si = new SurfaceImage(mFormat);
} else {
si = new SurfaceImage(mHardwareBufferFormat, mDataSpace);
}
return acquireNextSurfaceImage(si) == ACQUIRE_SUCCESS ? si : null; return acquireNextSurfaceImage(si) == ACQUIRE_SUCCESS ? si : null;
} }
@@ -565,7 +557,7 @@ public class ImageReader implements AutoCloseable {
// A null image will eventually be returned if ImageReader is already closed. // A null image will eventually be returned if ImageReader is already closed.
int status = ACQUIRE_NO_BUFS; int status = ACQUIRE_NO_BUFS;
if (mIsReaderValid) { if (mIsReaderValid) {
status = nativeImageSetup(si, mUseLegacyImageFormat); status = nativeImageSetup(si);
} }
switch (status) { switch (status) {
@@ -619,11 +611,7 @@ public class ImageReader implements AutoCloseable {
// Initialize with reader format, but can be overwritten by native if the image // Initialize with reader format, but can be overwritten by native if the image
// format is different from the reader format. // format is different from the reader format.
SurfaceImage si; SurfaceImage si;
if (mUseLegacyImageFormat) { si = new SurfaceImage(mFormat);
si = new SurfaceImage(mFormat);
} else {
si = new SurfaceImage(mHardwareBufferFormat, mDataSpace);
}
int status = acquireNextSurfaceImage(si); int status = acquireNextSurfaceImage(si);
switch (status) { switch (status) {
@@ -1094,8 +1082,6 @@ public class ImageReader implements AutoCloseable {
private final @NamedDataSpace int mDataSpace; private final @NamedDataSpace int mDataSpace;
private final boolean mUseLegacyImageFormat;
/** /**
* This field is used by native code, do not access or modify. * This field is used by native code, do not access or modify.
*/ */
@@ -1136,12 +1122,6 @@ public class ImageReader implements AutoCloseable {
mDataSpace = ImageReader.this.mDataSpace; mDataSpace = ImageReader.this.mDataSpace;
} }
SurfaceImage(int hardwareBufferFormat, int dataSpace) {
mHardwareBufferFormat = hardwareBufferFormat;
mDataSpace = dataSpace;
mFormat = PublicFormatUtils.getPublicFormat(mHardwareBufferFormat, mDataSpace);
}
@Override @Override
public void close() { public void close() {
synchronized (this.mCloseLock) { synchronized (this.mCloseLock) {
@@ -1159,12 +1139,10 @@ public class ImageReader implements AutoCloseable {
// update mFormat only if ImageReader is initialized by factory pattern. // update mFormat only if ImageReader is initialized by factory pattern.
// if using builder pattern, mFormat has been updated upon initialization. // if using builder pattern, mFormat has been updated upon initialization.
// no need update here. // no need update here.
if (ImageReader.this.mUseLegacyImageFormat) { int readerFormat = ImageReader.this.getImageFormat();
int readerFormat = ImageReader.this.getImageFormat(); // Assume opaque reader always produce opaque images.
// Assume opaque reader always produce opaque images. mFormat = (readerFormat == ImageFormat.PRIVATE) ? readerFormat :
mFormat = (readerFormat == ImageFormat.PRIVATE) ? readerFormat : nativeGetFormat(readerFormat);
nativeGetFormat(readerFormat);
}
return mFormat; return mFormat;
} }
@@ -1263,8 +1241,8 @@ public class ImageReader implements AutoCloseable {
throwISEIfImageIsInvalid(); throwISEIfImageIsInvalid();
if (mPlanes == null) { if (mPlanes == null) {
mPlanes = nativeCreatePlanes(ImageReader.this.mNumPlanes, ImageReader.this.mFormat, mPlanes = nativeCreatePlanes(ImageReader.this.mNumPlanes,
ImageReader.this.mUsage); ImageReader.this.mHardwareBufferFormat, ImageReader.this.mUsage);
} }
// Shallow copy is fine. // Shallow copy is fine.
return mPlanes.clone(); return mPlanes.clone();
@@ -1395,7 +1373,7 @@ public class ImageReader implements AutoCloseable {
private AtomicBoolean mIsDetached = new AtomicBoolean(false); private AtomicBoolean mIsDetached = new AtomicBoolean(false);
private synchronized native SurfacePlane[] nativeCreatePlanes(int numPlanes, private synchronized native SurfacePlane[] nativeCreatePlanes(int numPlanes,
int readerFormat, long readerUsage); int hardwareBufferFormat, long readerUsage);
private synchronized native int nativeGetWidth(); private synchronized native int nativeGetWidth();
private synchronized native int nativeGetHeight(); private synchronized native int nativeGetHeight();
private synchronized native int nativeGetFormat(int readerFormat); private synchronized native int nativeGetFormat(int readerFormat);
@@ -1418,7 +1396,7 @@ public class ImageReader implements AutoCloseable {
* @see #ACQUIRE_NO_BUFS * @see #ACQUIRE_NO_BUFS
* @see #ACQUIRE_MAX_IMAGES * @see #ACQUIRE_MAX_IMAGES
*/ */
private synchronized native int nativeImageSetup(Image i, boolean legacyValidateImageFormat); private synchronized native int nativeImageSetup(Image i);
/** /**
* @hide * @hide

View File

@@ -29,7 +29,6 @@ import android.hardware.DataSpace.NamedDataSpace;
import android.hardware.HardwareBuffer; import android.hardware.HardwareBuffer;
import android.hardware.HardwareBuffer.Usage; import android.hardware.HardwareBuffer.Usage;
import android.hardware.SyncFence; import android.hardware.SyncFence;
import android.hardware.camera2.params.StreamConfigurationMap;
import android.hardware.camera2.utils.SurfaceUtils; import android.hardware.camera2.utils.SurfaceUtils;
import android.os.Handler; import android.os.Handler;
import android.os.Looper; import android.os.Looper;
@@ -249,7 +248,7 @@ public class ImageWriter implements AutoCloseable {
} }
private void initializeImageWriter(Surface surface, int maxImages, private void initializeImageWriter(Surface surface, int maxImages,
boolean useSurfaceImageFormatInfo, boolean useLegacyImageFormat, int imageFormat, boolean useSurfaceImageFormatInfo, int imageFormat,
int hardwareBufferFormat, int dataSpace, int width, int height, long usage) { int hardwareBufferFormat, int dataSpace, int width, int height, long usage) {
if (surface == null || maxImages < 1) { if (surface == null || maxImages < 1) {
throw new IllegalArgumentException("Illegal input argument: surface " + surface throw new IllegalArgumentException("Illegal input argument: surface " + surface
@@ -265,32 +264,11 @@ public class ImageWriter implements AutoCloseable {
if (useSurfaceImageFormatInfo) { if (useSurfaceImageFormatInfo) {
// nativeInit internally overrides UNKNOWN format. So does surface format query after // nativeInit internally overrides UNKNOWN format. So does surface format query after
// nativeInit and before getEstimatedNativeAllocBytes(). // nativeInit and before getEstimatedNativeAllocBytes().
imageFormat = SurfaceUtils.getSurfaceFormat(surface); mHardwareBufferFormat = hardwareBufferFormat = SurfaceUtils.getSurfaceFormat(surface);
mHardwareBufferFormat = PublicFormatUtils.getHalFormat(imageFormat); mDataSpace = dataSpace = SurfaceUtils.getSurfaceDataspace(surface);
mDataSpace = PublicFormatUtils.getHalDataspace(imageFormat); imageFormat = PublicFormatUtils.getPublicFormat(hardwareBufferFormat, dataSpace);
} }
// Several public formats use the same native HAL_PIXEL_FORMAT_BLOB. The native
// allocation estimation sequence depends on the public formats values. To avoid
// possible errors, convert where necessary.
if (imageFormat == StreamConfigurationMap.HAL_PIXEL_FORMAT_BLOB) {
int surfaceDataspace = SurfaceUtils.getSurfaceDataspace(surface);
switch (surfaceDataspace) {
case StreamConfigurationMap.HAL_DATASPACE_DEPTH:
imageFormat = ImageFormat.DEPTH_POINT_CLOUD;
break;
case StreamConfigurationMap.HAL_DATASPACE_DYNAMIC_DEPTH:
imageFormat = ImageFormat.DEPTH_JPEG;
break;
case StreamConfigurationMap.HAL_DATASPACE_HEIF:
imageFormat = ImageFormat.HEIC;
break;
default:
imageFormat = ImageFormat.JPEG;
}
mHardwareBufferFormat = PublicFormatUtils.getHalFormat(imageFormat);
mDataSpace = PublicFormatUtils.getHalDataspace(imageFormat);
}
// Estimate the native buffer allocation size and register it so it gets accounted for // Estimate the native buffer allocation size and register it so it gets accounted for
// during GC. Note that this doesn't include the buffers required by the buffer queue // during GC. Note that this doesn't include the buffers required by the buffer queue
// itself and the buffers requested by the producer. // itself and the buffers requested by the producer.
@@ -301,19 +279,20 @@ public class ImageWriter implements AutoCloseable {
mWidth = width == -1 ? surfSize.getWidth() : width; mWidth = width == -1 ? surfSize.getWidth() : width;
mHeight = height == -1 ? surfSize.getHeight() : height; mHeight = height == -1 ? surfSize.getHeight() : height;
mEstimatedNativeAllocBytes = mEstimatedNativeAllocBytes = ImageUtils.getEstimatedNativeAllocBytes(mWidth, mHeight,
ImageUtils.getEstimatedNativeAllocBytes(mWidth, mHeight, imageFormat, /*buffer count*/ 1);
useLegacyImageFormat ? imageFormat : hardwareBufferFormat, /*buffer count*/ 1);
VMRuntime.getRuntime().registerNativeAllocation(mEstimatedNativeAllocBytes); VMRuntime.getRuntime().registerNativeAllocation(mEstimatedNativeAllocBytes);
} }
private ImageWriter(Surface surface, int maxImages, boolean useSurfaceImageFormatInfo, private ImageWriter(Surface surface, int maxImages, boolean useSurfaceImageFormatInfo,
int imageFormat, int width, int height) { int imageFormat, int width, int height) {
mMaxImages = maxImages; mMaxImages = maxImages;
mHardwareBufferFormat = PublicFormatUtils.getHalFormat(imageFormat); if (!useSurfaceImageFormatInfo) {
mDataSpace = PublicFormatUtils.getHalDataspace(imageFormat); mHardwareBufferFormat = PublicFormatUtils.getHalFormat(imageFormat);
mDataSpace = PublicFormatUtils.getHalDataspace(imageFormat);
}
initializeImageWriter(surface, maxImages, useSurfaceImageFormatInfo, true, initializeImageWriter(surface, maxImages, useSurfaceImageFormatInfo,
imageFormat, mHardwareBufferFormat, mDataSpace, width, height, mUsage); imageFormat, mHardwareBufferFormat, mDataSpace, width, height, mUsage);
} }
@@ -321,10 +300,12 @@ public class ImageWriter implements AutoCloseable {
int imageFormat, int width, int height, long usage) { int imageFormat, int width, int height, long usage) {
mMaxImages = maxImages; mMaxImages = maxImages;
mUsage = usage; mUsage = usage;
mHardwareBufferFormat = PublicFormatUtils.getHalFormat(imageFormat); if (!useSurfaceImageFormatInfo) {
mDataSpace = PublicFormatUtils.getHalDataspace(imageFormat); mHardwareBufferFormat = PublicFormatUtils.getHalFormat(imageFormat);
mDataSpace = PublicFormatUtils.getHalDataspace(imageFormat);
}
initializeImageWriter(surface, maxImages, useSurfaceImageFormatInfo, true, initializeImageWriter(surface, maxImages, useSurfaceImageFormatInfo,
imageFormat, mHardwareBufferFormat, mDataSpace, width, height, usage); imageFormat, mHardwareBufferFormat, mDataSpace, width, height, usage);
} }
@@ -337,15 +318,13 @@ public class ImageWriter implements AutoCloseable {
// and retrieve corresponding hardwareBufferFormat and dataSpace here. // and retrieve corresponding hardwareBufferFormat and dataSpace here.
if (useSurfaceImageFormatInfo) { if (useSurfaceImageFormatInfo) {
imageFormat = ImageFormat.UNKNOWN; imageFormat = ImageFormat.UNKNOWN;
mHardwareBufferFormat = PublicFormatUtils.getHalFormat(imageFormat);
mDataSpace = PublicFormatUtils.getHalDataspace(imageFormat);
} else { } else {
imageFormat = PublicFormatUtils.getPublicFormat(hardwareBufferFormat, dataSpace); imageFormat = PublicFormatUtils.getPublicFormat(hardwareBufferFormat, dataSpace);
mHardwareBufferFormat = hardwareBufferFormat; mHardwareBufferFormat = hardwareBufferFormat;
mDataSpace = dataSpace; mDataSpace = dataSpace;
} }
initializeImageWriter(surface, maxImages, useSurfaceImageFormatInfo, false, initializeImageWriter(surface, maxImages, useSurfaceImageFormatInfo,
imageFormat, hardwareBufferFormat, dataSpace, width, height, usage); imageFormat, hardwareBufferFormat, dataSpace, width, height, usage);
} }
@@ -764,13 +743,15 @@ public class ImageWriter implements AutoCloseable {
// need do some cleanup to make sure no orphaned // need do some cleanup to make sure no orphaned
// buffer caused leak. // buffer caused leak.
Rect crop = image.getCropRect(); Rect crop = image.getCropRect();
int hardwareBufferFormat = PublicFormatUtils.getHalFormat(image.getFormat());
if (image.getNativeContext() != 0) { if (image.getNativeContext() != 0) {
nativeAttachAndQueueImage(mNativeContext, image.getNativeContext(), image.getFormat(), nativeAttachAndQueueImage(mNativeContext, image.getNativeContext(),
image.getTimestamp(), image.getDataSpace(), crop.left, crop.top, crop.right, hardwareBufferFormat, image.getTimestamp(), image.getDataSpace(),
crop.bottom, image.getTransform(), image.getScalingMode()); crop.left, crop.top, crop.right, crop.bottom, image.getTransform(),
image.getScalingMode());
} else { } else {
GraphicBuffer gb = GraphicBuffer.createFromHardwareBuffer(image.getHardwareBuffer()); GraphicBuffer gb = GraphicBuffer.createFromHardwareBuffer(image.getHardwareBuffer());
nativeAttachAndQueueGraphicBuffer(mNativeContext, gb, image.getFormat(), nativeAttachAndQueueGraphicBuffer(mNativeContext, gb, hardwareBufferFormat,
image.getTimestamp(), image.getDataSpace(), crop.left, crop.top, crop.right, image.getTimestamp(), image.getDataSpace(), crop.left, crop.top, crop.right,
crop.bottom, image.getTransform(), image.getScalingMode()); crop.bottom, image.getTransform(), image.getScalingMode());
gb.destroy(); gb.destroy();
@@ -1161,8 +1142,7 @@ public class ImageWriter implements AutoCloseable {
if (mPlanes == null) { if (mPlanes == null) {
int numPlanes = ImageUtils.getNumPlanesForFormat(getFormat()); int numPlanes = ImageUtils.getNumPlanesForFormat(getFormat());
mPlanes = nativeCreatePlanes(numPlanes, getOwner().getFormat(), mPlanes = nativeCreatePlanes(numPlanes, getOwner().getFormat());
getOwner().getDataSpace());
} }
return mPlanes.clone(); return mPlanes.clone();
@@ -1270,8 +1250,7 @@ public class ImageWriter implements AutoCloseable {
} }
// Create the SurfacePlane object and fill the information // Create the SurfacePlane object and fill the information
private synchronized native SurfacePlane[] nativeCreatePlanes(int numPlanes, int writerFmt, private synchronized native SurfacePlane[] nativeCreatePlanes(int numPlanes, int writerFmt);
int dataSpace);
private synchronized native int nativeGetWidth(); private synchronized native int nativeGetWidth();
@@ -1298,10 +1277,10 @@ public class ImageWriter implements AutoCloseable {
int transform, int scalingMode); int transform, int scalingMode);
private synchronized native int nativeAttachAndQueueImage(long nativeCtx, private synchronized native int nativeAttachAndQueueImage(long nativeCtx,
long imageNativeBuffer, int imageFormat, long timestampNs, int dataSpace, long imageNativeBuffer, int hardwareBufferFormat, long timestampNs, int dataSpace,
int left, int top, int right, int bottom, int transform, int scalingMode); int left, int top, int right, int bottom, int transform, int scalingMode);
private synchronized native int nativeAttachAndQueueGraphicBuffer(long nativeCtx, private synchronized native int nativeAttachAndQueueGraphicBuffer(long nativeCtx,
GraphicBuffer graphicBuffer, int imageFormat, long timestampNs, int dataSpace, GraphicBuffer graphicBuffer, int hardwareBufferFormat, long timestampNs, int dataSpace,
int left, int top, int right, int bottom, int transform, int scalingMode); int left, int top, int right, int bottom, int transform, int scalingMode);
private synchronized native void cancelImage(long nativeCtx, Image image); private synchronized native void cancelImage(long nativeCtx, Image image);

View File

@@ -375,11 +375,11 @@ static void ImageReader_classInit(JNIEnv* env, jclass clazz)
} }
static void ImageReader_init(JNIEnv* env, jobject thiz, jobject weakThiz, jint width, jint height, static void ImageReader_init(JNIEnv* env, jobject thiz, jobject weakThiz, jint width, jint height,
jint maxImages, jlong ndkUsage, jint nativeFormat, jint dataSpace) { jint maxImages, jlong ndkUsage, jint nativeHalFormat, jint dataSpace) {
status_t res; status_t res;
ALOGV("%s: width:%d, height: %d, nativeFormat: %d, maxImages:%d", ALOGV("%s: width:%d, height: %d, nativeHalFormat: %d, maxImages:%d",
__FUNCTION__, width, height, nativeFormat, maxImages); __FUNCTION__, width, height, nativeHalFormat, maxImages);
android_dataspace nativeDataspace = static_cast<android_dataspace>(dataSpace); android_dataspace nativeDataspace = static_cast<android_dataspace>(dataSpace);
@@ -395,7 +395,7 @@ static void ImageReader_init(JNIEnv* env, jobject thiz, jobject weakThiz, jint w
BufferQueue::createBufferQueue(&gbProducer, &gbConsumer); BufferQueue::createBufferQueue(&gbProducer, &gbConsumer);
sp<BufferItemConsumer> bufferConsumer; sp<BufferItemConsumer> bufferConsumer;
String8 consumerName = String8::format("ImageReader-%dx%df%xm%d-%d-%d", String8 consumerName = String8::format("ImageReader-%dx%df%xm%d-%d-%d",
width, height, nativeFormat, maxImages, getpid(), width, height, nativeHalFormat, maxImages, getpid(),
createProcessUniqueId()); createProcessUniqueId());
uint64_t consumerUsage = uint64_t consumerUsage =
android_hardware_HardwareBuffer_convertToGrallocUsageBits(ndkUsage); android_hardware_HardwareBuffer_convertToGrallocUsageBits(ndkUsage);
@@ -404,8 +404,8 @@ static void ImageReader_init(JNIEnv* env, jobject thiz, jobject weakThiz, jint w
/*controlledByApp*/true); /*controlledByApp*/true);
if (bufferConsumer == nullptr) { if (bufferConsumer == nullptr) {
jniThrowExceptionFmt(env, "java/lang/RuntimeException", jniThrowExceptionFmt(env, "java/lang/RuntimeException",
"Failed to allocate native buffer consumer for format 0x%x and usage 0x%x", "Failed to allocate native buffer consumer for hal format 0x%x and usage 0x%x",
nativeFormat, consumerUsage); nativeHalFormat, consumerUsage);
return; return;
} }
@@ -419,7 +419,7 @@ static void ImageReader_init(JNIEnv* env, jobject thiz, jobject weakThiz, jint w
ctx->setProducer(gbProducer); ctx->setProducer(gbProducer);
bufferConsumer->setFrameAvailableListener(ctx); bufferConsumer->setFrameAvailableListener(ctx);
ImageReader_setNativeContext(env, thiz, ctx); ImageReader_setNativeContext(env, thiz, ctx);
ctx->setBufferFormat(nativeFormat); ctx->setBufferFormat(nativeHalFormat);
ctx->setBufferDataspace(nativeDataspace); ctx->setBufferDataspace(nativeDataspace);
ctx->setBufferWidth(width); ctx->setBufferWidth(width);
ctx->setBufferHeight(height); ctx->setBufferHeight(height);
@@ -428,14 +428,14 @@ static void ImageReader_init(JNIEnv* env, jobject thiz, jobject weakThiz, jint w
res = bufferConsumer->setDefaultBufferSize(width, height); res = bufferConsumer->setDefaultBufferSize(width, height);
if (res != OK) { if (res != OK) {
jniThrowExceptionFmt(env, "java/lang/IllegalStateException", jniThrowExceptionFmt(env, "java/lang/IllegalStateException",
"Failed to set buffer consumer default size (%dx%d) for format 0x%x", "Failed to set buffer consumer default size (%dx%d) for Hal format 0x%x",
width, height, nativeFormat); width, height, nativeHalFormat);
return; return;
} }
res = bufferConsumer->setDefaultBufferFormat(nativeFormat); res = bufferConsumer->setDefaultBufferFormat(nativeHalFormat);
if (res != OK) { if (res != OK) {
jniThrowExceptionFmt(env, "java/lang/IllegalStateException", jniThrowExceptionFmt(env, "java/lang/IllegalStateException",
"Failed to set buffer consumer default format 0x%x", nativeFormat); "Failed to set buffer consumer default Halformat 0x%x", nativeHalFormat);
return; return;
} }
res = bufferConsumer->setDefaultBufferDataSpace(nativeDataspace); res = bufferConsumer->setDefaultBufferDataSpace(nativeDataspace);
@@ -522,8 +522,7 @@ static void ImageReader_imageRelease(JNIEnv* env, jobject thiz, jobject image)
ALOGV("%s: Image (format: 0x%x) has been released", __FUNCTION__, ctx->getBufferFormat()); ALOGV("%s: Image (format: 0x%x) has been released", __FUNCTION__, ctx->getBufferFormat());
} }
static jint ImageReader_imageSetup(JNIEnv* env, jobject thiz, jobject image, static jint ImageReader_imageSetup(JNIEnv* env, jobject thiz, jobject image) {
jboolean legacyValidateImageFormat) {
ALOGV("%s:", __FUNCTION__); ALOGV("%s:", __FUNCTION__);
JNIImageReaderContext* ctx = ImageReader_getContext(env, thiz); JNIImageReaderContext* ctx = ImageReader_getContext(env, thiz);
if (ctx == NULL) { if (ctx == NULL) {
@@ -577,29 +576,29 @@ static jint ImageReader_imageSetup(JNIEnv* env, jobject thiz, jobject image,
int outputWidth = getBufferWidth(buffer); int outputWidth = getBufferWidth(buffer);
int outputHeight = getBufferHeight(buffer); int outputHeight = getBufferHeight(buffer);
int imgReaderFmt = ctx->getBufferFormat(); int imgReaderHalFmt = ctx->getBufferFormat();
int imageReaderWidth = ctx->getBufferWidth(); int imageReaderWidth = ctx->getBufferWidth();
int imageReaderHeight = ctx->getBufferHeight(); int imageReaderHeight = ctx->getBufferHeight();
int bufferFormat = buffer->mGraphicBuffer->getPixelFormat(); int bufferFormat = buffer->mGraphicBuffer->getPixelFormat();
if ((bufferFormat != HAL_PIXEL_FORMAT_BLOB) && (imgReaderFmt != HAL_PIXEL_FORMAT_BLOB) && if ((bufferFormat != HAL_PIXEL_FORMAT_BLOB) && (imgReaderHalFmt != HAL_PIXEL_FORMAT_BLOB) &&
(imageReaderWidth != outputWidth || imageReaderHeight != outputHeight)) { (imageReaderWidth != outputWidth || imageReaderHeight != outputHeight)) {
ALOGV("%s: Producer buffer size: %dx%d, doesn't match ImageReader configured size: %dx%d", ALOGV("%s: Producer buffer size: %dx%d, doesn't match ImageReader configured size: %dx%d",
__FUNCTION__, outputWidth, outputHeight, imageReaderWidth, imageReaderHeight); __FUNCTION__, outputWidth, outputHeight, imageReaderWidth, imageReaderHeight);
} }
if (legacyValidateImageFormat && imgReaderFmt != bufferFormat) { if (imgReaderHalFmt != bufferFormat) {
if (imgReaderFmt == HAL_PIXEL_FORMAT_YCbCr_420_888 && if (imgReaderHalFmt == HAL_PIXEL_FORMAT_YCbCr_420_888 &&
isPossiblyYUV(bufferFormat)) { isPossiblyYUV(bufferFormat)) {
// Treat formats that are compatible with flexible YUV // Treat formats that are compatible with flexible YUV
// (HAL_PIXEL_FORMAT_YCbCr_420_888) as HAL_PIXEL_FORMAT_YCbCr_420_888. // (HAL_PIXEL_FORMAT_YCbCr_420_888) as HAL_PIXEL_FORMAT_YCbCr_420_888.
ALOGV("%s: Treat buffer format to 0x%x as HAL_PIXEL_FORMAT_YCbCr_420_888", ALOGV("%s: Treat buffer format to 0x%x as HAL_PIXEL_FORMAT_YCbCr_420_888",
__FUNCTION__, bufferFormat); __FUNCTION__, bufferFormat);
} else if (imgReaderFmt == HAL_PIXEL_FORMAT_YCBCR_P010 && } else if (imgReaderHalFmt == HAL_PIXEL_FORMAT_YCBCR_P010 &&
isPossibly10BitYUV(bufferFormat)) { isPossibly10BitYUV(bufferFormat)) {
// Treat formats that are compatible with flexible 10-bit YUV // Treat formats that are compatible with flexible 10-bit YUV
// (HAL_PIXEL_FORMAT_YCBCR_P010) as HAL_PIXEL_FORMAT_YCBCR_P010. // (HAL_PIXEL_FORMAT_YCBCR_P010) as HAL_PIXEL_FORMAT_YCBCR_P010.
ALOGV("%s: Treat buffer format to 0x%x as HAL_PIXEL_FORMAT_YCBCR_P010", ALOGV("%s: Treat buffer format to 0x%x as HAL_PIXEL_FORMAT_YCBCR_P010",
__FUNCTION__, bufferFormat); __FUNCTION__, bufferFormat);
} else if (imgReaderFmt == HAL_PIXEL_FORMAT_BLOB && } else if (imgReaderHalFmt == HAL_PIXEL_FORMAT_BLOB &&
bufferFormat == HAL_PIXEL_FORMAT_RGBA_8888) { bufferFormat == HAL_PIXEL_FORMAT_RGBA_8888) {
// Using HAL_PIXEL_FORMAT_RGBA_8888 Gralloc buffers containing JPEGs to get around // Using HAL_PIXEL_FORMAT_RGBA_8888 Gralloc buffers containing JPEGs to get around
// SW write limitations for (b/17379185). // SW write limitations for (b/17379185).
@@ -842,7 +841,7 @@ static jobjectArray ImageReader_createImagePlanes(JNIEnv* env, jobject /*thiz*/,
} }
static jobjectArray Image_createSurfacePlanes(JNIEnv* env, jobject thiz, static jobjectArray Image_createSurfacePlanes(JNIEnv* env, jobject thiz,
int numPlanes, int readerFormat, uint64_t ndkReaderUsage) int numPlanes, int halReaderFormat, uint64_t ndkReaderUsage)
{ {
ALOGV("%s: create SurfacePlane array with size %d", __FUNCTION__, numPlanes); ALOGV("%s: create SurfacePlane array with size %d", __FUNCTION__, numPlanes);
int rowStride = 0; int rowStride = 0;
@@ -851,9 +850,6 @@ static jobjectArray Image_createSurfacePlanes(JNIEnv* env, jobject thiz,
uint32_t dataSize = 0; uint32_t dataSize = 0;
jobject byteBuffer = NULL; jobject byteBuffer = NULL;
PublicFormat publicReaderFormat = static_cast<PublicFormat>(readerFormat);
int halReaderFormat = mapPublicFormatToHalFormat(publicReaderFormat);
if (isFormatOpaque(halReaderFormat) && numPlanes > 0) { if (isFormatOpaque(halReaderFormat) && numPlanes > 0) {
String8 msg; String8 msg;
msg.appendFormat("Format 0x%x is opaque, thus not writable, the number of planes (%d)" msg.appendFormat("Format 0x%x is opaque, thus not writable, the number of planes (%d)"
@@ -963,7 +959,7 @@ static const JNINativeMethod gImageReaderMethods[] = {
{"nativeInit", "(Ljava/lang/Object;IIIJII)V", (void*)ImageReader_init }, {"nativeInit", "(Ljava/lang/Object;IIIJII)V", (void*)ImageReader_init },
{"nativeClose", "()V", (void*)ImageReader_close }, {"nativeClose", "()V", (void*)ImageReader_close },
{"nativeReleaseImage", "(Landroid/media/Image;)V", (void*)ImageReader_imageRelease }, {"nativeReleaseImage", "(Landroid/media/Image;)V", (void*)ImageReader_imageRelease },
{"nativeImageSetup", "(Landroid/media/Image;Z)I", (void*)ImageReader_imageSetup }, {"nativeImageSetup", "(Landroid/media/Image;)I", (void*)ImageReader_imageSetup },
{"nativeGetSurface", "()Landroid/view/Surface;", (void*)ImageReader_getSurface }, {"nativeGetSurface", "()Landroid/view/Surface;", (void*)ImageReader_getSurface },
{"nativeDetachImage", "(Landroid/media/Image;)I", (void*)ImageReader_detachImage }, {"nativeDetachImage", "(Landroid/media/Image;)I", (void*)ImageReader_detachImage },
{"nativeCreateImagePlanes", {"nativeCreateImagePlanes",

View File

@@ -415,7 +415,9 @@ static jlong ImageWriter_init(JNIEnv* env, jobject thiz, jobject weakThiz, jobje
// Get the dimension and format of the producer. // Get the dimension and format of the producer.
sp<ANativeWindow> anw = producer; sp<ANativeWindow> anw = producer;
int32_t width, height, surfaceFormat; int32_t width, height, surfaceHalFormat;
int32_t surfaceFormat = 0;
int32_t surfaceDataspace = 0;
if (userWidth < 0) { if (userWidth < 0) {
if ((res = anw->query(anw.get(), NATIVE_WINDOW_WIDTH, &width)) != OK) { if ((res = anw->query(anw.get(), NATIVE_WINDOW_WIDTH, &width)) != OK) {
ALOGE("%s: Query Surface width failed: %s (%d)", __FUNCTION__, strerror(-res), res); ALOGE("%s: Query Surface width failed: %s (%d)", __FUNCTION__, strerror(-res), res);
@@ -451,11 +453,18 @@ static jlong ImageWriter_init(JNIEnv* env, jobject thiz, jobject weakThiz, jobje
// Query surface format if no valid user format is specified, otherwise, override surface format // Query surface format if no valid user format is specified, otherwise, override surface format
// with user format. // with user format.
if (useSurfaceImageFormatInfo) { if (useSurfaceImageFormatInfo) {
if ((res = anw->query(anw.get(), NATIVE_WINDOW_FORMAT, &surfaceFormat)) != OK) { // retrieve hal format
if ((res = anw->query(anw.get(), NATIVE_WINDOW_FORMAT, &surfaceHalFormat)) != OK) {
ALOGE("%s: Query Surface format failed: %s (%d)", __FUNCTION__, strerror(-res), res); ALOGE("%s: Query Surface format failed: %s (%d)", __FUNCTION__, strerror(-res), res);
jniThrowRuntimeException(env, "Failed to query Surface format"); jniThrowRuntimeException(env, "Failed to query Surface format");
return 0; return 0;
} }
if ((res = anw->query(
anw.get(), NATIVE_WINDOW_DEFAULT_DATASPACE, &surfaceDataspace)) != OK) {
ALOGE("%s: Query Surface dataspace failed: %s (%d)", __FUNCTION__, strerror(-res), res);
jniThrowRuntimeException(env, "Failed to query Surface dataspace");
return 0;
}
} else { } else {
// Set consumer buffer format to user specified format // Set consumer buffer format to user specified format
android_dataspace nativeDataspace = static_cast<android_dataspace>(dataSpace); android_dataspace nativeDataspace = static_cast<android_dataspace>(dataSpace);
@@ -475,17 +484,22 @@ static jlong ImageWriter_init(JNIEnv* env, jobject thiz, jobject weakThiz, jobje
return 0; return 0;
} }
ctx->setBufferDataSpace(nativeDataspace); ctx->setBufferDataSpace(nativeDataspace);
surfaceFormat = static_cast<int32_t>(mapHalFormatDataspaceToPublicFormat( surfaceDataspace = dataSpace;
hardwareBufferFormat, nativeDataspace)); surfaceHalFormat = hardwareBufferFormat;
} }
ctx->setBufferFormat(surfaceFormat); ctx->setBufferFormat(surfaceHalFormat);
ctx->setBufferDataSpace(static_cast<android_dataspace>(surfaceDataspace));
// update class.mWriterFormat
surfaceFormat = static_cast<int32_t>(mapHalFormatDataspaceToPublicFormat(
surfaceHalFormat, static_cast<android_dataspace>(surfaceDataspace)));
env->SetIntField(thiz, env->SetIntField(thiz,
gImageWriterClassInfo.mWriterFormat, reinterpret_cast<jint>(surfaceFormat)); gImageWriterClassInfo.mWriterFormat, reinterpret_cast<jint>(surfaceFormat));
// ndkUsage == -1 means setUsage in ImageWriter class is not called. // ndkUsage == -1 means setUsage in ImageWriter class is not called.
// skip usage setting if setUsage in ImageWriter is not called and imageformat is opaque. // skip usage setting if setUsage in ImageWriter is not called and imageformat is opaque.
if (!(ndkUsage == -1 && isFormatOpaque(surfaceFormat))) { if (!(ndkUsage == -1 && isFormatOpaque(surfaceHalFormat))) {
if (ndkUsage == -1) { if (ndkUsage == -1) {
ndkUsage = GRALLOC_USAGE_SW_WRITE_OFTEN; ndkUsage = GRALLOC_USAGE_SW_WRITE_OFTEN;
} }
@@ -809,7 +823,7 @@ static status_t attachAndQeueuGraphicBuffer(JNIEnv* env, JNIImageWriterContext *
} }
static jint ImageWriter_attachAndQueueImage(JNIEnv* env, jobject thiz, jlong nativeCtx, static jint ImageWriter_attachAndQueueImage(JNIEnv* env, jobject thiz, jlong nativeCtx,
jlong nativeBuffer, jint imageFormat, jlong timestampNs, jint dataSpace, jlong nativeBuffer, jint nativeHalFormat, jlong timestampNs, jint dataSpace,
jint left, jint top, jint right, jint bottom, jint transform, jint scalingMode) { jint left, jint top, jint right, jint bottom, jint transform, jint scalingMode) {
ALOGV("%s", __FUNCTION__); ALOGV("%s", __FUNCTION__);
JNIImageWriterContext* const ctx = reinterpret_cast<JNIImageWriterContext *>(nativeCtx); JNIImageWriterContext* const ctx = reinterpret_cast<JNIImageWriterContext *>(nativeCtx);
@@ -820,7 +834,7 @@ static jint ImageWriter_attachAndQueueImage(JNIEnv* env, jobject thiz, jlong nat
} }
sp<Surface> surface = ctx->getProducer(); sp<Surface> surface = ctx->getProducer();
if (isFormatOpaque(imageFormat) != isFormatOpaque(ctx->getBufferFormat())) { if (isFormatOpaque(ctx->getBufferFormat()) != isFormatOpaque(nativeHalFormat)) {
jniThrowException(env, "java/lang/IllegalStateException", jniThrowException(env, "java/lang/IllegalStateException",
"Trying to attach an opaque image into a non-opaque ImageWriter, or vice versa"); "Trying to attach an opaque image into a non-opaque ImageWriter, or vice versa");
return -1; return -1;
@@ -840,8 +854,8 @@ static jint ImageWriter_attachAndQueueImage(JNIEnv* env, jobject thiz, jlong nat
} }
static jint ImageWriter_attachAndQueueGraphicBuffer(JNIEnv* env, jobject thiz, jlong nativeCtx, static jint ImageWriter_attachAndQueueGraphicBuffer(JNIEnv* env, jobject thiz, jlong nativeCtx,
jobject buffer, jint format, jlong timestampNs, jint dataSpace, jint left, jint top, jobject buffer, jint nativeHalFormat, jlong timestampNs, jint dataSpace,
jint right, jint bottom, jint transform, jint scalingMode) { jint left, jint top, jint right, jint bottom, jint transform, jint scalingMode) {
ALOGV("%s", __FUNCTION__); ALOGV("%s", __FUNCTION__);
JNIImageWriterContext* const ctx = reinterpret_cast<JNIImageWriterContext *>(nativeCtx); JNIImageWriterContext* const ctx = reinterpret_cast<JNIImageWriterContext *>(nativeCtx);
if (ctx == NULL || thiz == NULL) { if (ctx == NULL || thiz == NULL) {
@@ -851,7 +865,7 @@ static jint ImageWriter_attachAndQueueGraphicBuffer(JNIEnv* env, jobject thiz, j
} }
sp<Surface> surface = ctx->getProducer(); sp<Surface> surface = ctx->getProducer();
if (isFormatOpaque(format) != isFormatOpaque(ctx->getBufferFormat())) { if (isFormatOpaque(ctx->getBufferFormat()) != isFormatOpaque(nativeHalFormat)) {
jniThrowException(env, "java/lang/IllegalStateException", jniThrowException(env, "java/lang/IllegalStateException",
"Trying to attach an opaque image into a non-opaque ImageWriter, or vice versa"); "Trying to attach an opaque image into a non-opaque ImageWriter, or vice versa");
return -1; return -1;
@@ -1028,32 +1042,32 @@ static void Image_getLockedImage(JNIEnv* env, jobject thiz, LockedImage *image)
} }
static bool Image_getLockedImageInfo(JNIEnv* env, LockedImage* buffer, int idx, static bool Image_getLockedImageInfo(JNIEnv* env, LockedImage* buffer, int idx,
int32_t writerFormat, uint8_t **base, uint32_t *size, int *pixelStride, int *rowStride) { int32_t halFormat, uint8_t **base, uint32_t *size, int *pixelStride, int *rowStride) {
ALOGV("%s", __FUNCTION__); ALOGV("%s", __FUNCTION__);
status_t res = getLockedImageInfo(buffer, idx, writerFormat, base, size, status_t res = getLockedImageInfo(buffer, idx, halFormat, base, size,
pixelStride, rowStride); pixelStride, rowStride);
if (res != OK) { if (res != OK) {
jniThrowExceptionFmt(env, "java/lang/UnsupportedOperationException", jniThrowExceptionFmt(env, "java/lang/UnsupportedOperationException",
"Pixel format: 0x%x is unsupported", writerFormat); "Pixel format: 0x%x is unsupported", halFormat);
return false; return false;
} }
return true; return true;
} }
static jobjectArray Image_createSurfacePlanes(JNIEnv* env, jobject thiz, static jobjectArray Image_createSurfacePlanes(JNIEnv* env, jobject thiz,
int numPlanes, int writerFormat, int dataSpace) { int numPlanes, int writerFormat) {
ALOGV("%s: create SurfacePlane array with size %d", __FUNCTION__, numPlanes); ALOGV("%s: create SurfacePlane array with size %d", __FUNCTION__, numPlanes);
int rowStride, pixelStride; int rowStride, pixelStride;
uint8_t *pData; uint8_t *pData;
uint32_t dataSize; uint32_t dataSize;
jobject byteBuffer; jobject byteBuffer;
int halFormat = mapPublicFormatToHalFormat(static_cast<PublicFormat>(writerFormat));
int format = Image_getFormat(env, thiz, dataSpace); if (isFormatOpaque(halFormat) && numPlanes > 0) {
if (isFormatOpaque(format) && numPlanes > 0) {
String8 msg; String8 msg;
msg.appendFormat("Format 0x%x is opaque, thus not writable, the number of planes (%d)" msg.appendFormat("Format 0x%x is opaque, thus not writable, the number of planes (%d)"
" must be 0", format, numPlanes); " must be 0", writerFormat, numPlanes);
jniThrowException(env, "java/lang/IllegalArgumentException", msg.string()); jniThrowException(env, "java/lang/IllegalArgumentException", msg.string());
return NULL; return NULL;
} }
@@ -1065,7 +1079,8 @@ static jobjectArray Image_createSurfacePlanes(JNIEnv* env, jobject thiz,
" probably out of memory"); " probably out of memory");
return NULL; return NULL;
} }
if (isFormatOpaque(format)) {
if (isFormatOpaque(halFormat)) {
return surfacePlanes; return surfacePlanes;
} }
@@ -1074,10 +1089,8 @@ static jobjectArray Image_createSurfacePlanes(JNIEnv* env, jobject thiz,
Image_getLockedImage(env, thiz, &lockedImg); Image_getLockedImage(env, thiz, &lockedImg);
// Create all SurfacePlanes // Create all SurfacePlanes
PublicFormat publicWriterFormat = static_cast<PublicFormat>(writerFormat);
writerFormat = mapPublicFormatToHalFormat(publicWriterFormat);
for (int i = 0; i < numPlanes; i++) { for (int i = 0; i < numPlanes; i++) {
if (!Image_getLockedImageInfo(env, &lockedImg, i, writerFormat, if (!Image_getLockedImageInfo(env, &lockedImg, i, halFormat,
&pData, &dataSize, &pixelStride, &rowStride)) { &pData, &dataSize, &pixelStride, &rowStride)) {
return NULL; return NULL;
} }
@@ -1119,7 +1132,7 @@ static JNINativeMethod gImageWriterMethods[] = {
}; };
static JNINativeMethod gImageMethods[] = { static JNINativeMethod gImageMethods[] = {
{"nativeCreatePlanes", "(III)[Landroid/media/ImageWriter$WriterSurfaceImage$SurfacePlane;", {"nativeCreatePlanes", "(II)[Landroid/media/ImageWriter$WriterSurfaceImage$SurfacePlane;",
(void*)Image_createSurfacePlanes }, (void*)Image_createSurfacePlanes },
{"nativeGetWidth", "()I", (void*)Image_getWidth }, {"nativeGetWidth", "()I", (void*)Image_getWidth },
{"nativeGetHeight", "()I", (void*)Image_getHeight }, {"nativeGetHeight", "()I", (void*)Image_getHeight },