Merge "Fix cts flaky issue on adt3 device."
This commit is contained in:
@@ -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
|
||||||
|
|||||||
@@ -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;
|
||||||
|
if (!useSurfaceImageFormatInfo) {
|
||||||
mHardwareBufferFormat = PublicFormatUtils.getHalFormat(imageFormat);
|
mHardwareBufferFormat = PublicFormatUtils.getHalFormat(imageFormat);
|
||||||
mDataSpace = PublicFormatUtils.getHalDataspace(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;
|
||||||
|
if (!useSurfaceImageFormatInfo) {
|
||||||
mHardwareBufferFormat = PublicFormatUtils.getHalFormat(imageFormat);
|
mHardwareBufferFormat = PublicFormatUtils.getHalFormat(imageFormat);
|
||||||
mDataSpace = PublicFormatUtils.getHalDataspace(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);
|
||||||
|
|||||||
@@ -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",
|
||||||
|
|||||||
@@ -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 },
|
||||||
|
|||||||
Reference in New Issue
Block a user