summaryrefslogtreecommitdiffstats
path: root/media
diff options
context:
space:
mode:
authorRuben Brunk <rubenbrunk@google.com>2014-09-23 23:35:43 -0700
committerRuben Brunk <rubenbrunk@google.com>2014-09-24 10:43:12 -0700
commit0fd198ad89ec9c600bb1761b10d938146c28bb98 (patch)
tree413982c700e2e5c76df3800ebdb8ec2ddc17a9bb /media
parent54fee6862871170e2db0d02262a4724b7dad1485 (diff)
downloadframeworks_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.java9
-rw-r--r--media/jni/android_media_ImageReader.cpp59
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 },
};