Merge "Camera: Populate Image tranformation in reader and writer" into pi-dev

This commit is contained in:
TreeHugger Robot
2018-03-20 12:33:37 +00:00
committed by Android (Google) Code Review
6 changed files with 67 additions and 9 deletions

View File

@@ -185,6 +185,13 @@ public abstract class Image implements AutoCloseable {
*/
public abstract long getTimestamp();
/**
* Get the transformation associated with this frame.
* @return The window transformation that needs to be applied for this frame.
* @hide
*/
public abstract int getTransform();
/**
* Get the {@link android.hardware.HardwareBuffer HardwareBuffer} handle of the input image
* intended for GPU and/or hardware access.

View File

@@ -875,6 +875,12 @@ public class ImageReader implements AutoCloseable {
return mTimestamp;
}
@Override
public int getTransform() {
throwISEIfImageIsInvalid();
return mTransform;
}
@Override
public HardwareBuffer getHardwareBuffer() {
throwISEIfImageIsInvalid();
@@ -1013,6 +1019,11 @@ public class ImageReader implements AutoCloseable {
*/
private long mTimestamp;
/**
* This field is set by native code during nativeImageSetup().
*/
private int mTransform;
private SurfacePlane[] mPlanes;
private int mFormat = ImageFormat.UNKNOWN;
// If this image is detached from the ImageReader.

View File

@@ -371,7 +371,7 @@ public class ImageWriter implements AutoCloseable {
Rect crop = image.getCropRect();
nativeQueueInputImage(mNativeContext, image, image.getTimestamp(), crop.left, crop.top,
crop.right, crop.bottom);
crop.right, crop.bottom, image.getTransform());
/**
* Only remove and cleanup the Images that are owned by this
@@ -557,7 +557,8 @@ public class ImageWriter implements AutoCloseable {
// buffer caused leak.
Rect crop = image.getCropRect();
nativeAttachAndQueueImage(mNativeContext, image.getNativeContext(), image.getFormat(),
image.getTimestamp(), crop.left, crop.top, crop.right, crop.bottom);
image.getTimestamp(), crop.left, crop.top, crop.right, crop.bottom,
image.getTransform());
}
/**
@@ -674,6 +675,8 @@ public class ImageWriter implements AutoCloseable {
private final long DEFAULT_TIMESTAMP = Long.MIN_VALUE;
private long mTimestamp = DEFAULT_TIMESTAMP;
private int mTransform = 0; //Default no transform
public WriterSurfaceImage(ImageWriter writer) {
mOwner = writer;
}
@@ -710,6 +713,13 @@ public class ImageWriter implements AutoCloseable {
return mHeight;
}
@Override
public int getTransform() {
throwISEIfImageIsInvalid();
return mTransform;
}
@Override
public long getTimestamp() {
throwISEIfImageIsInvalid();
@@ -856,11 +866,11 @@ public class ImageWriter implements AutoCloseable {
private synchronized native void nativeDequeueInputImage(long nativeCtx, Image wi);
private synchronized native void nativeQueueInputImage(long nativeCtx, Image image,
long timestampNs, int left, int top, int right, int bottom);
long timestampNs, int left, int top, int right, int bottom, int transform);
private synchronized native int nativeAttachAndQueueImage(long nativeCtx,
long imageNativeBuffer, int imageFormat, long timestampNs, int left,
int top, int right, int bottom);
int top, int right, int bottom, int transform);
private synchronized native void cancelImage(long nativeCtx, Image image);

View File

@@ -3528,6 +3528,8 @@ final public class MediaCodec {
private final static int TYPE_YUV = 1;
private final int mTransform = 0; //Default no transform
@Override
public int getFormat() {
throwISEIfImageIsInvalid();
@@ -3546,6 +3548,12 @@ final public class MediaCodec {
return mWidth;
}
@Override
public int getTransform() {
throwISEIfImageIsInvalid();
return mTransform;
}
@Override
public long getTimestamp() {
throwISEIfImageIsInvalid();

View File

@@ -45,6 +45,7 @@
#define ANDROID_MEDIA_IMAGEREADER_CTX_JNI_ID "mNativeContext"
#define ANDROID_MEDIA_SURFACEIMAGE_BUFFER_JNI_ID "mNativeBuffer"
#define ANDROID_MEDIA_SURFACEIMAGE_TS_JNI_ID "mTimestamp"
#define ANDROID_MEDIA_SURFACEIMAGE_TF_JNI_ID "mTransform"
#define CONSUMER_BUFFER_USAGE_UNKNOWN 0;
// ----------------------------------------------------------------------------
@@ -66,6 +67,7 @@ static struct {
static struct {
jfieldID mNativeBuffer;
jfieldID mTimestamp;
jfieldID mTransform;
jfieldID mPlanes;
} gSurfaceImageClassInfo;
@@ -307,6 +309,12 @@ static void ImageReader_classInit(JNIEnv* env, jclass clazz)
"can't find android/graphics/ImageReader.%s",
ANDROID_MEDIA_SURFACEIMAGE_TS_JNI_ID);
gSurfaceImageClassInfo.mTransform = env->GetFieldID(
imageClazz, ANDROID_MEDIA_SURFACEIMAGE_TF_JNI_ID, "I");
LOG_ALWAYS_FATAL_IF(gSurfaceImageClassInfo.mTransform == NULL,
"can't find android/graphics/ImageReader.%s",
ANDROID_MEDIA_SURFACEIMAGE_TF_JNI_ID);
gSurfaceImageClassInfo.mPlanes = env->GetFieldID(
imageClazz, "mPlanes", "[Landroid/media/ImageReader$SurfaceImage$SurfacePlane;");
LOG_ALWAYS_FATAL_IF(gSurfaceImageClassInfo.mPlanes == NULL,
@@ -596,6 +604,8 @@ static jint ImageReader_imageSetup(JNIEnv* env, jobject thiz, jobject image) {
Image_setBufferItem(env, image, buffer);
env->SetLongField(image, gSurfaceImageClassInfo.mTimestamp,
static_cast<jlong>(buffer->mTimestamp));
env->SetIntField(image, gSurfaceImageClassInfo.mTransform,
static_cast<jint>(buffer->mTransform));
return ACQUIRE_SUCCESS;
}

View File

@@ -421,7 +421,7 @@ static void ImageWriter_cancelImage(JNIEnv* env, jobject thiz, jlong nativeCtx,
}
static void ImageWriter_queueImage(JNIEnv* env, jobject thiz, jlong nativeCtx, jobject image,
jlong timestampNs, jint left, jint top, jint right, jint bottom) {
jlong timestampNs, jint left, jint top, jint right, jint bottom, jint transform) {
ALOGV("%s", __FUNCTION__);
JNIImageWriterContext* const ctx = reinterpret_cast<JNIImageWriterContext *>(nativeCtx);
if (ctx == NULL || thiz == NULL) {
@@ -465,6 +465,12 @@ static void ImageWriter_queueImage(JNIEnv* env, jobject thiz, jlong nativeCtx, j
return;
}
res = native_window_set_buffers_transform(anw.get(), transform);
if (res != OK) {
jniThrowRuntimeException(env, "Set transform failed");
return;
}
// Finally, queue input buffer
res = anw->queueBuffer(anw.get(), buffer, fenceFd);
if (res != OK) {
@@ -487,7 +493,7 @@ static void ImageWriter_queueImage(JNIEnv* env, jobject thiz, jlong nativeCtx, j
static jint ImageWriter_attachAndQueueImage(JNIEnv* env, jobject thiz, jlong nativeCtx,
jlong nativeBuffer, jint imageFormat, jlong timestampNs, jint left, jint top,
jint right, jint bottom) {
jint right, jint bottom, jint transform) {
ALOGV("%s", __FUNCTION__);
JNIImageWriterContext* const ctx = reinterpret_cast<JNIImageWriterContext *>(nativeCtx);
if (ctx == NULL || thiz == NULL) {
@@ -530,7 +536,7 @@ static jint ImageWriter_attachAndQueueImage(JNIEnv* env, jobject thiz, jlong nat
}
sp < ANativeWindow > anw = surface;
// Step 2. Set timestamp and crop. Note that we do not need unlock the image because
// Step 2. Set timestamp, crop and transform. Note that we do not need unlock the image because
// it was not locked.
ALOGV("timestamp to be queued: %" PRId64, timestampNs);
res = native_window_set_buffers_timestamp(anw.get(), timestampNs);
@@ -550,6 +556,12 @@ static jint ImageWriter_attachAndQueueImage(JNIEnv* env, jobject thiz, jlong nat
return res;
}
res = native_window_set_buffers_transform(anw.get(), transform);
if (res != OK) {
jniThrowRuntimeException(env, "Set transform failed");
return res;
}
// Step 3. Queue Image.
res = anw->queueBuffer(anw.get(), buffer->mGraphicBuffer.get(), /*fenceFd*/
-1);
@@ -785,9 +797,9 @@ static JNINativeMethod gImageWriterMethods[] = {
{"nativeInit", "(Ljava/lang/Object;Landroid/view/Surface;II)J",
(void*)ImageWriter_init },
{"nativeClose", "(J)V", (void*)ImageWriter_close },
{"nativeAttachAndQueueImage", "(JJIJIIII)I", (void*)ImageWriter_attachAndQueueImage },
{"nativeAttachAndQueueImage", "(JJIJIIIII)I", (void*)ImageWriter_attachAndQueueImage },
{"nativeDequeueInputImage", "(JLandroid/media/Image;)V", (void*)ImageWriter_dequeueImage },
{"nativeQueueInputImage", "(JLandroid/media/Image;JIIII)V", (void*)ImageWriter_queueImage },
{"nativeQueueInputImage", "(JLandroid/media/Image;JIIIII)V", (void*)ImageWriter_queueImage },
{"cancelImage", "(JLandroid/media/Image;)V", (void*)ImageWriter_cancelImage },
};