diff options
author | Ruben Brunk <rubenbrunk@google.com> | 2014-09-30 03:42:13 -0700 |
---|---|---|
committer | Ruben Brunk <rubenbrunk@google.com> | 2014-09-30 13:54:20 -0700 |
commit | 0c79884076405bc36c0fb4f1bce27f883b97d64c (patch) | |
tree | d340d650e22d13fdd346c2d5504a8ee798a4170f | |
parent | bc156ba430d286aaab8deb7bbb3bccc655cd2e92 (diff) |
camera2: Use valid dimensions for RGBA8888 gralloc buffers.
Bug: 17675571
- All of the mistakes were made. Unmake them.
Change-Id: I23ff7a553347d4d9588c728219f4bf0604ba2e38
3 files changed, 25 insertions, 20 deletions
diff --git a/core/java/android/hardware/camera2/legacy/RequestThreadManager.java b/core/java/android/hardware/camera2/legacy/RequestThreadManager.java index fd9590151ad2..35deb71e4bcf 100644 --- a/core/java/android/hardware/camera2/legacy/RequestThreadManager.java +++ b/core/java/android/hardware/camera2/legacy/RequestThreadManager.java @@ -16,11 +16,13 @@ package android.hardware.camera2.legacy; +import android.graphics.ImageFormat; import android.graphics.SurfaceTexture; import android.hardware.Camera; import android.hardware.camera2.CameraCharacteristics; import android.hardware.camera2.CaptureRequest; import android.hardware.camera2.impl.CameraDeviceImpl; +import android.hardware.camera2.params.StreamConfigurationMap; import android.hardware.camera2.utils.LongParcelable; import android.hardware.camera2.utils.SizeAreaComparator; import android.hardware.camera2.impl.CameraMetadataNative; @@ -36,6 +38,7 @@ import android.view.Surface; import java.io.IOException; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.List; @@ -208,18 +211,23 @@ public class RequestThreadManager { int totalSize = data.length + LegacyCameraDevice.nativeGetJpegFooterSize(); totalSize = (totalSize + 3) & ~0x3; // round up to nearest octonibble + LegacyCameraDevice.setNextTimestamp(s, timestamp); if (USE_BLOB_FORMAT_OVERRIDE) { // Override to RGBA_8888 format. LegacyCameraDevice.setSurfaceFormat(s, LegacyMetadataMapper.HAL_PIXEL_FORMAT_RGBA_8888); - // divide by 4 if using RGBA format (width is in pixels, not bytes). - totalSize >>= 2; + + int dimen = (int) Math.ceil(Math.sqrt(totalSize)); + dimen = (dimen + 0xf) & ~0xf; // round up to nearest multiple of 16 + LegacyCameraDevice.setSurfaceDimens(s, dimen, dimen); + LegacyCameraDevice.produceFrame(s, data, dimen, dimen, + CameraMetadataNative.NATIVE_JPEG_FORMAT); + } else { + LegacyCameraDevice.setSurfaceDimens(s, totalSize, /*height*/1); + LegacyCameraDevice.produceFrame(s, data, totalSize, /*height*/1, + CameraMetadataNative.NATIVE_JPEG_FORMAT); } - LegacyCameraDevice.setSurfaceDimens(s, totalSize, /*height*/1); - LegacyCameraDevice.setNextTimestamp(s, timestamp); - LegacyCameraDevice.produceFrame(s, data, totalSize, /*height*/1, - CameraMetadataNative.NATIVE_JPEG_FORMAT); } } catch (LegacyExceptionUtils.BufferQueueAbandonedException e) { Log.w(TAG, "Surface abandoned, dropping frame. ", e); diff --git a/core/jni/android_hardware_camera2_legacy_LegacyCameraDevice.cpp b/core/jni/android_hardware_camera2_legacy_LegacyCameraDevice.cpp index b90e493d1bc2..8440a0e7c493 100644 --- a/core/jni/android_hardware_camera2_legacy_LegacyCameraDevice.cpp +++ b/core/jni/android_hardware_camera2_legacy_LegacyCameraDevice.cpp @@ -193,12 +193,13 @@ static status_t produceFrame(const sp<ANativeWindow>& anw, if (err != NO_ERROR) return err; sp<GraphicBuffer> buf(new GraphicBuffer(anb, /*keepOwnership*/false)); - uint32_t gBufWidth = buf->getWidth(); - uint32_t gBufHeight = buf->getHeight(); - if (gBufWidth != width || gBufHeight != height) { + uint32_t grallocBufWidth = buf->getWidth(); + uint32_t grallocBufHeight = buf->getHeight(); + uint32_t grallocBufStride = buf->getStride(); + if (grallocBufWidth != width || grallocBufHeight != height) { ALOGE("%s: Received gralloc buffer with bad dimensions %" PRIu32 "x%" PRIu32 - ", expecting dimensions %zu x %zu", __FUNCTION__, gBufWidth, gBufHeight, - width, height); + ", expecting dimensions %zu x %zu", __FUNCTION__, grallocBufWidth, + grallocBufHeight, width, height); return BAD_VALUE; } @@ -210,11 +211,12 @@ static status_t produceFrame(const sp<ANativeWindow>& anw, return err; } - uint64_t tmpSize = width * height; + uint64_t tmpSize = (pixelFmt == HAL_PIXEL_FORMAT_BLOB) ? grallocBufWidth : + 4 * grallocBufHeight * grallocBufWidth; if (bufFmt != pixelFmt) { if (bufFmt == HAL_PIXEL_FORMAT_RGBA_8888 && pixelFmt == HAL_PIXEL_FORMAT_BLOB) { ALOGV("%s: Using BLOB to RGBA format override.", __FUNCTION__); - tmpSize *= 4; + tmpSize = 4 * (grallocBufWidth + grallocBufStride * (grallocBufHeight - 1)); } else { ALOGW("%s: Format mismatch in produceFrame: expecting format %#" PRIx32 ", but received buffer with format %#" PRIx32, __FUNCTION__, pixelFmt, bufFmt); @@ -311,17 +313,12 @@ static status_t produceFrame(const sp<ANativeWindow>& anw, int8_t* img = NULL; struct camera3_jpeg_blob footer = { jpeg_blob_id: CAMERA3_JPEG_BLOB_ID, - jpeg_size: (uint32_t)width + jpeg_size: (uint32_t)bufferLength }; size_t totalJpegSize = bufferLength + sizeof(footer); totalJpegSize = (totalJpegSize + 3) & ~0x3; // round up to nearest octonibble - if (height != 1) { - ALOGE("%s: Invalid height set for JPEG buffer output, %zu", __FUNCTION__, height); - return BAD_VALUE; - } - if (totalJpegSize > totalSizeBytes) { ALOGE("%s: Pixel buffer needs size %zu, cannot fit in gralloc buffer of size %zu", __FUNCTION__, totalJpegSize, totalSizeBytes); diff --git a/media/jni/android_media_ImageReader.cpp b/media/jni/android_media_ImageReader.cpp index f4eb4594e198..aaff9a2ce217 100644 --- a/media/jni/android_media_ImageReader.cpp +++ b/media/jni/android_media_ImageReader.cpp @@ -294,7 +294,7 @@ static uint32_t Image_getJpegSize(CpuConsumer::LockedBuffer* buffer, bool usingR uint8_t* jpegBuffer = buffer->data; if (usingRGBAOverride) { - width *= 4; + width = (buffer->width + buffer->stride * (buffer->height - 1)) * 4; } // First check for JPEG transport header at the end of the buffer |