diff options
author | Ruben Brunk <rubenbrunk@google.com> | 2014-09-23 23:35:43 -0700 |
---|---|---|
committer | Ruben Brunk <rubenbrunk@google.com> | 2014-09-24 10:43:12 -0700 |
commit | 0fd198ad89ec9c600bb1761b10d938146c28bb98 (patch) | |
tree | 413982c700e2e5c76df3800ebdb8ec2ddc17a9bb /media | |
parent | 54fee6862871170e2db0d02262a4724b7dad1485 (diff) | |
download | frameworks_base-0fd198ad89ec9c600bb1761b10d938146c28bb98.zip frameworks_base-0fd198ad89ec9c600bb1761b10d938146c28bb98.tar.gz frameworks_base-0fd198ad89ec9c600bb1761b10d938146c28bb98.tar.bz2 |
camera2: Hide JPEGs in RGBA gralloc buffers.
Bug: 17379185
- WAR for SW Write usage flags being unavailable on
certain devices for JPEG (blob) format buffers.
Change-Id: Ic7299785b743f35dd47264b9d1cea01a88b71d91
Diffstat (limited to 'media')
-rw-r--r-- | media/java/android/media/ImageReader.java | 9 | ||||
-rw-r--r-- | media/jni/android_media_ImageReader.cpp | 59 |
2 files changed, 49 insertions, 19 deletions
diff --git a/media/java/android/media/ImageReader.java b/media/java/android/media/ImageReader.java index b786f94..b541454 100644 --- a/media/java/android/media/ImageReader.java +++ b/media/java/android/media/ImageReader.java @@ -642,7 +642,7 @@ public class ImageReader implements AutoCloseable { private void createSurfacePlanes() { mPlanes = new SurfacePlane[ImageReader.this.mNumPlanes]; for (int i = 0; i < ImageReader.this.mNumPlanes; i++) { - mPlanes[i] = nativeCreatePlane(i); + mPlanes[i] = nativeCreatePlane(i, ImageReader.this.mFormat); } } private class SurfacePlane extends android.media.Image.Plane { @@ -661,7 +661,8 @@ public class ImageReader implements AutoCloseable { if (mBuffer != null) { return mBuffer; } else { - mBuffer = SurfaceImage.this.nativeImageGetBuffer(mIndex); + mBuffer = SurfaceImage.this.nativeImageGetBuffer(mIndex, + ImageReader.this.mFormat); // Set the byteBuffer order according to host endianness (native order), // otherwise, the byteBuffer order defaults to ByteOrder.BIG_ENDIAN. return mBuffer.order(ByteOrder.nativeOrder()); @@ -711,8 +712,8 @@ public class ImageReader implements AutoCloseable { private SurfacePlane[] mPlanes; private boolean mIsImageValid; - private synchronized native ByteBuffer nativeImageGetBuffer(int idx); - private synchronized native SurfacePlane nativeCreatePlane(int idx); + private synchronized native ByteBuffer nativeImageGetBuffer(int idx, int readerFormat); + private synchronized native SurfacePlane nativeCreatePlane(int idx, int readerFormat); } private synchronized native void nativeInit(Object weakSelf, int w, int h, diff --git a/media/jni/android_media_ImageReader.cpp b/media/jni/android_media_ImageReader.cpp index fa4439d..a734774 100644 --- a/media/jni/android_media_ImageReader.cpp +++ b/media/jni/android_media_ImageReader.cpp @@ -317,8 +317,18 @@ static uint32_t Image_getJpegSize(CpuConsumer::LockedBuffer* buffer) return size; } +static int32_t applyFormatOverrides(int32_t bufferFormat, int32_t readerCtxFormat) +{ + // Using HAL_PIXEL_FORMAT_RGBA_8888 gralloc buffers containing JPEGs to get around SW + // write limitations for some platforms (b/17379185). + if (readerCtxFormat == HAL_PIXEL_FORMAT_BLOB && bufferFormat == HAL_PIXEL_FORMAT_RGBA_8888) { + return HAL_PIXEL_FORMAT_BLOB; + } + return bufferFormat; +} + static void Image_getLockedBufferInfo(JNIEnv* env, CpuConsumer::LockedBuffer* buffer, int idx, - uint8_t **base, uint32_t *size) + uint8_t **base, uint32_t *size, int32_t readerFormat) { ALOG_ASSERT(buffer != NULL, "Input buffer is NULL!!!"); ALOG_ASSERT(base != NULL, "base is NULL!!!"); @@ -334,6 +344,8 @@ static void Image_getLockedBufferInfo(JNIEnv* env, CpuConsumer::LockedBuffer* bu dataSize = ySize = cSize = cStride = 0; int32_t fmt = buffer->format; + + fmt = applyFormatOverrides(fmt, readerFormat); switch (fmt) { case HAL_PIXEL_FORMAT_YCbCr_420_888: pData = @@ -458,7 +470,8 @@ static void Image_getLockedBufferInfo(JNIEnv* env, CpuConsumer::LockedBuffer* bu *size = dataSize; } -static jint Image_imageGetPixelStride(JNIEnv* env, CpuConsumer::LockedBuffer* buffer, int idx) +static jint Image_imageGetPixelStride(JNIEnv* env, CpuConsumer::LockedBuffer* buffer, int idx, + int32_t readerFormat) { ALOGV("%s: buffer index: %d", __FUNCTION__, idx); ALOG_ASSERT((idx < IMAGE_READER_MAX_NUM_PLANES) && (idx >= 0), "Index is out of range:%d", idx); @@ -467,6 +480,9 @@ static jint Image_imageGetPixelStride(JNIEnv* env, CpuConsumer::LockedBuffer* bu ALOG_ASSERT(buffer != NULL, "buffer is NULL"); int32_t fmt = buffer->format; + + fmt = applyFormatOverrides(fmt, readerFormat); + switch (fmt) { case HAL_PIXEL_FORMAT_YCbCr_420_888: pixelStride = (idx == 0) ? 1 : buffer->chromaStep; @@ -515,7 +531,8 @@ static jint Image_imageGetPixelStride(JNIEnv* env, CpuConsumer::LockedBuffer* bu return pixelStride; } -static jint Image_imageGetRowStride(JNIEnv* env, CpuConsumer::LockedBuffer* buffer, int idx) +static jint Image_imageGetRowStride(JNIEnv* env, CpuConsumer::LockedBuffer* buffer, int idx, + int32_t readerFormat) { ALOGV("%s: buffer index: %d", __FUNCTION__, idx); ALOG_ASSERT((idx < IMAGE_READER_MAX_NUM_PLANES) && (idx >= 0)); @@ -525,6 +542,8 @@ static jint Image_imageGetRowStride(JNIEnv* env, CpuConsumer::LockedBuffer* buff int32_t fmt = buffer->format; + fmt = applyFormatOverrides(fmt, readerFormat); + switch (fmt) { case HAL_PIXEL_FORMAT_YCbCr_420_888: rowStride = (idx == 0) ? buffer->stride : buffer->chromaStride; @@ -777,9 +796,10 @@ static jint ImageReader_imageSetup(JNIEnv* env, jobject thiz, outputHeight = buffer->crop.getHeight(); } + int imgReaderFmt = ctx->getBufferFormat(); int imageReaderWidth = ctx->getBufferWidth(); int imageReaderHeight = ctx->getBufferHeight(); - if ((buffer->format != HAL_PIXEL_FORMAT_BLOB) && + if ((buffer->format != HAL_PIXEL_FORMAT_BLOB) && (imgReaderFmt != HAL_PIXEL_FORMAT_BLOB) && (imageReaderWidth != outputWidth || imageReaderHeight > outputHeight)) { /** * For video decoder, the buffer height is actually the vertical stride, @@ -795,15 +815,19 @@ static jint ImageReader_imageSetup(JNIEnv* env, jobject thiz, return -1; } - int imgReaderFmt = ctx->getBufferFormat(); int bufFmt = buffer->format; if (imgReaderFmt != bufFmt) { - // Special casing for when producer switches to a format compatible with flexible YUV - // (HAL_PIXEL_FORMAT_YCbCr_420_888). + if (imgReaderFmt == HAL_PIXEL_FORMAT_YCbCr_420_888 && (bufFmt == HAL_PIXEL_FORMAT_YCrCb_420_SP || bufFmt == HAL_PIXEL_FORMAT_YV12)) { + // Special casing for when producer switches to a format compatible with flexible YUV + // (HAL_PIXEL_FORMAT_YCbCr_420_888). ctx->setBufferFormat(bufFmt); - ALOGV("%s: Overriding buffer format YUV_420_888 to %x.", __FUNCTION__, bufFmt); + ALOGD("%s: Overriding buffer format YUV_420_888 to %x.", __FUNCTION__, bufFmt); + } else if (imgReaderFmt == HAL_PIXEL_FORMAT_BLOB && bufFmt == HAL_PIXEL_FORMAT_RGBA_8888) { + // Using HAL_PIXEL_FORMAT_RGBA_8888 gralloc buffers containing JPEGs to get around SW + // write limitations for (b/17379185). + ALOGD("%s: Receiving JPEG in HAL_PIXEL_FORMAT_RGBA_8888 buffer.", __FUNCTION__); } else { // Return the buffer to the queue. consumer->unlockBuffer(*buffer); @@ -843,7 +867,7 @@ static jobject ImageReader_getSurface(JNIEnv* env, jobject thiz) return android_view_Surface_createFromIGraphicBufferProducer(env, gbp); } -static jobject Image_createSurfacePlane(JNIEnv* env, jobject thiz, int idx) +static jobject Image_createSurfacePlane(JNIEnv* env, jobject thiz, int idx, int readerFormat) { int rowStride, pixelStride; ALOGV("%s: buffer index: %d", __FUNCTION__, idx); @@ -854,8 +878,11 @@ static jobject Image_createSurfacePlane(JNIEnv* env, jobject thiz, int idx) if (buffer == NULL) { jniThrowException(env, "java/lang/IllegalStateException", "Image was released"); } - rowStride = Image_imageGetRowStride(env, buffer, idx); - pixelStride = Image_imageGetPixelStride(env, buffer, idx); + + readerFormat = Image_getPixelFormat(env, readerFormat); + + rowStride = Image_imageGetRowStride(env, buffer, idx, readerFormat); + pixelStride = Image_imageGetPixelStride(env, buffer, idx, readerFormat); jobject surfPlaneObj = env->NewObject(gSurfacePlaneClassInfo.clazz, gSurfacePlaneClassInfo.ctor, thiz, idx, rowStride, pixelStride); @@ -863,7 +890,7 @@ static jobject Image_createSurfacePlane(JNIEnv* env, jobject thiz, int idx) return surfPlaneObj; } -static jobject Image_getByteBuffer(JNIEnv* env, jobject thiz, int idx) +static jobject Image_getByteBuffer(JNIEnv* env, jobject thiz, int idx, int readerFormat) { uint8_t *base = NULL; uint32_t size = 0; @@ -877,8 +904,10 @@ static jobject Image_getByteBuffer(JNIEnv* env, jobject thiz, int idx) jniThrowException(env, "java/lang/IllegalStateException", "Image was released"); } + readerFormat = Image_getPixelFormat(env, readerFormat); + // Create byteBuffer from native buffer - Image_getLockedBufferInfo(env, buffer, idx, &base, &size); + Image_getLockedBufferInfo(env, buffer, idx, &base, &size, readerFormat); if (size > static_cast<uint32_t>(INT32_MAX)) { // Byte buffer have 'int capacity', so check the range @@ -910,8 +939,8 @@ static JNINativeMethod gImageReaderMethods[] = { }; static JNINativeMethod gImageMethods[] = { - {"nativeImageGetBuffer", "(I)Ljava/nio/ByteBuffer;", (void*)Image_getByteBuffer }, - {"nativeCreatePlane", "(I)Landroid/media/ImageReader$SurfaceImage$SurfacePlane;", + {"nativeImageGetBuffer", "(II)Ljava/nio/ByteBuffer;", (void*)Image_getByteBuffer }, + {"nativeCreatePlane", "(II)Landroid/media/ImageReader$SurfaceImage$SurfacePlane;", (void*)Image_createSurfacePlane }, }; |