summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Treehugger Robot <android-test-infra-autosubmit@system.gserviceaccount.com> 2024-12-13 15:49:23 -0800
committer Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com> 2024-12-13 15:49:23 -0800
commitaf4443ef0ec957dd1d82eb8218ae4e4ec4ffbe54 (patch)
tree4671fbe7c15f34d4e3eb1c4ff31e1415398c9cf5
parent106d5b9454cbbf0d7288c9dc8d9d3d6a6b1b866c (diff)
parent66b289cb9255432d412eda60dc8e555156a80aee (diff)
Merge "Add support for P210 format in various java apis" into main am: 66b289cb92
Original change: https://android-review.googlesource.com/c/platform/frameworks/base/+/3271452 Change-Id: I8cfbaf785686cd49e6cc51817fb5c034d5b9e3a9 Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
-rw-r--r--media/java/android/media/Image.java9
-rw-r--r--media/java/android/media/ImageUtils.java9
-rw-r--r--media/java/android/media/MediaCodec.java9
-rw-r--r--media/jni/android_media_Utils.cpp139
4 files changed, 157 insertions, 9 deletions
diff --git a/media/java/android/media/Image.java b/media/java/android/media/Image.java
index d6fe68253be6..486063ed5f6b 100644
--- a/media/java/android/media/Image.java
+++ b/media/java/android/media/Image.java
@@ -180,6 +180,15 @@ public abstract class Image implements AutoCloseable {
* a semi-planar format, the Cb plane can also be treated as an interleaved Cb/Cr plane.
* </td>
* </tr>
+ * <tr>
+ * <td>{@link android.graphics.ImageFormat#YCBCR_P210 YCBCR_P210}</td>
+ * <td>3</td>
+ * <td>P210 is a 4:2:2 YCbCr semiplanar format comprised of a WxH Y plane
+ * followed by a WxH Cb and Cr planes. Each sample is represented by a 16-bit
+ * little-endian value, with the lower 6 bits set to zero. Since this is guaranteed to be
+ * a semi-planar format, the Cb plane can also be treated as an interleaved Cb/Cr plane.
+ * </td>
+ * </tr>
* </table>
*
* @see android.graphics.ImageFormat
diff --git a/media/java/android/media/ImageUtils.java b/media/java/android/media/ImageUtils.java
index f4caad727407..83b056f2cb74 100644
--- a/media/java/android/media/ImageUtils.java
+++ b/media/java/android/media/ImageUtils.java
@@ -49,6 +49,7 @@ class ImageUtils {
case ImageFormat.YUV_420_888:
case ImageFormat.NV21:
case ImageFormat.YCBCR_P010:
+ case ImageFormat.YCBCR_P210:
return 3;
case ImageFormat.NV16:
return 2;
@@ -88,6 +89,7 @@ class ImageUtils {
switch(hardwareBufferFormat) {
case HardwareBuffer.YCBCR_420_888:
case HardwareBuffer.YCBCR_P010:
+ case HardwareBuffer.YCBCR_P210:
return 3;
case HardwareBuffer.RGBA_8888:
case HardwareBuffer.RGBX_8888:
@@ -269,6 +271,7 @@ class ImageUtils {
case PixelFormat.RGBA_8888:
case PixelFormat.RGBX_8888:
case PixelFormat.RGBA_1010102:
+ case ImageFormat.YCBCR_P210:
estimatedBytePerPixel = 4.0;
break;
default:
@@ -318,6 +321,12 @@ class ImageUtils {
return new Size(image.getWidth(), image.getHeight());
case ImageFormat.PRIVATE:
return new Size(0, 0);
+ case ImageFormat.YCBCR_P210:
+ if (planeIdx == 0) {
+ return new Size(image.getWidth(), image.getHeight());
+ } else {
+ return new Size(image.getWidth() / 2, image.getHeight());
+ }
default:
if (Log.isLoggable(IMAGEUTILS_LOG_TAG, Log.VERBOSE)) {
Log.v(IMAGEUTILS_LOG_TAG, "getEffectivePlaneSizeForImage() uses"
diff --git a/media/java/android/media/MediaCodec.java b/media/java/android/media/MediaCodec.java
index 82e950365850..36f62da651db 100644
--- a/media/java/android/media/MediaCodec.java
+++ b/media/java/android/media/MediaCodec.java
@@ -6158,11 +6158,14 @@ final public class MediaCodec {
buffer.limit(buffer.position() + Utils.divUp(bitDepth, 8)
+ (mHeight / vert - 1) * rowInc + (mWidth / horiz - 1) * colInc);
mPlanes[ix] = new MediaPlane(buffer.slice(), rowInc, colInc);
- if ((mFormat == ImageFormat.YUV_420_888 || mFormat == ImageFormat.YCBCR_P010)
+ if ((mFormat == ImageFormat.YUV_420_888 || mFormat == ImageFormat.YCBCR_P010
+ || mFormat == ImageFormat.YCBCR_P210)
&& ix == 1) {
cbPlaneOffset = planeOffset;
} else if ((mFormat == ImageFormat.YUV_420_888
- || mFormat == ImageFormat.YCBCR_P010) && ix == 2) {
+ || mFormat == ImageFormat.YCBCR_P010
+ || mFormat == ImageFormat.YCBCR_P210)
+ && ix == 2) {
crPlaneOffset = planeOffset;
}
}
@@ -6172,7 +6175,7 @@ final public class MediaCodec {
}
// Validate chroma semiplanerness.
- if (mFormat == ImageFormat.YCBCR_P010) {
+ if (mFormat == ImageFormat.YCBCR_P010 || mFormat == ImageFormat.YCBCR_P210) {
if (crPlaneOffset != cbPlaneOffset + planeOffsetInc) {
throw new UnsupportedOperationException("Invalid plane offsets"
+ " cbPlaneOffset: " + cbPlaneOffset + " crPlaneOffset: " + crPlaneOffset);
diff --git a/media/jni/android_media_Utils.cpp b/media/jni/android_media_Utils.cpp
index fbebbdcb8761..e8f8644a4503 100644
--- a/media/jni/android_media_Utils.cpp
+++ b/media/jni/android_media_Utils.cpp
@@ -17,13 +17,14 @@
// #define LOG_NDEBUG 0
#define LOG_TAG "AndroidMediaUtils"
+#include "android_media_Utils.h"
+
+#include <aidl/android/hardware/graphics/common/PixelFormat.h>
#include <aidl/android/hardware/graphics/common/PlaneLayoutComponentType.h>
#include <ui/GraphicBufferMapper.h>
#include <ui/GraphicTypes.h>
#include <utils/Log.h>
-#include "android_media_Utils.h"
-
#define ALIGN(x, mask) ( ((x) + (mask) - 1) & ~((mask) - 1) )
// Must be in sync with the value in HeicCompositeStream.cpp
@@ -33,6 +34,8 @@ namespace android {
// -----------Utility functions used by ImageReader/Writer JNI-----------------
+using AidlPixelFormat = aidl::android::hardware::graphics::common::PixelFormat;
+
enum {
IMAGE_MAX_NUM_PLANES = 3,
};
@@ -74,6 +77,7 @@ bool isPossiblyYUV(PixelFormat format) {
case HAL_PIXEL_FORMAT_BLOB:
case HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED:
case HAL_PIXEL_FORMAT_YCBCR_P010:
+ case static_cast<int>(AidlPixelFormat::YCBCR_P210):
return false;
case HAL_PIXEL_FORMAT_YV12:
@@ -105,6 +109,7 @@ bool isPossibly10BitYUV(PixelFormat format) {
return false;
case HAL_PIXEL_FORMAT_YCBCR_P010:
+ case static_cast<int>(AidlPixelFormat::YCBCR_P210):
default:
return true;
}
@@ -340,6 +345,47 @@ status_t getLockedImageInfo(LockedImage* buffer, int idx,
cb = buffer->data + ySize;
cr = cb + 2;
+ pData = (idx == 0) ? buffer->data : (idx == 1) ? cb : cr;
+ dataSize = (idx == 0) ? ySize : cSize;
+ rStride = buffer->stride * 2;
+ break;
+ case static_cast<int>(AidlPixelFormat::YCBCR_P210):
+ if (buffer->height % 2 != 0) {
+ ALOGE("YCBCR_P210: height (%d) should be a multiple of 2", buffer->height);
+ return BAD_VALUE;
+ }
+
+ if (buffer->width <= 0) {
+ ALOGE("YCBCR_P210: width (%d) should be a > 0", buffer->width);
+ return BAD_VALUE;
+ }
+
+ if (buffer->height <= 0) {
+ ALOGE("YCBCR_210: height (%d) should be a > 0", buffer->height);
+ return BAD_VALUE;
+ }
+ if (buffer->dataCb && buffer->dataCr) {
+ pData = (idx == 0) ? buffer->data : (idx == 1) ? buffer->dataCb : buffer->dataCr;
+ // only map until last pixel
+ if (idx == 0) {
+ pStride = 2;
+ rStride = buffer->stride;
+ dataSize = buffer->stride * (buffer->height - 1) + buffer->width * 2;
+ } else {
+ pStride = buffer->chromaStep;
+ rStride = buffer->chromaStride;
+ dataSize = buffer->chromaStride * (buffer->height - 1) +
+ buffer->chromaStep * (buffer->width / 2);
+ }
+ break;
+ }
+
+ ySize = (buffer->stride * 2) * buffer->height;
+ cSize = ySize;
+ pStride = (idx == 0) ? 2 : 4;
+ cb = buffer->data + ySize;
+ cr = cb + 2;
+
pData = (idx == 0) ? buffer->data : (idx == 1) ? cb : cr;
dataSize = (idx == 0) ? ySize : cSize;
rStride = buffer->stride * 2;
@@ -544,6 +590,80 @@ static status_t extractP010Gralloc4PlaneLayout(
return OK;
}
+static status_t extractP210Gralloc4PlaneLayout(sp<GraphicBuffer> buffer, void *pData, int format,
+ LockedImage *outputImage) {
+ using aidl::android::hardware::graphics::common::PlaneLayoutComponent;
+ using aidl::android::hardware::graphics::common::PlaneLayoutComponentType;
+
+ GraphicBufferMapper &mapper = GraphicBufferMapper::get();
+ std::vector<ui::PlaneLayout> planeLayouts;
+ status_t res = mapper.getPlaneLayouts(buffer->handle, &planeLayouts);
+ if (res != OK) {
+ return res;
+ }
+ constexpr int64_t Y_PLANE_COMPONENTS = int64_t(PlaneLayoutComponentType::Y);
+ constexpr int64_t CBCR_PLANE_COMPONENTS =
+ int64_t(PlaneLayoutComponentType::CB) | int64_t(PlaneLayoutComponentType::CR);
+ uint8_t *dataY = nullptr;
+ uint8_t *dataCb = nullptr;
+ uint8_t *dataCr = nullptr;
+ uint32_t strideY = 0;
+ uint32_t strideCbCr = 0;
+ for (const ui::PlaneLayout &layout : planeLayouts) {
+ ALOGV("gralloc4 plane: %s", layout.toString().c_str());
+ int64_t components = 0;
+ for (const PlaneLayoutComponent &component : layout.components) {
+ if (component.sizeInBits != 10) {
+ return BAD_VALUE;
+ }
+ components |= component.type.value;
+ }
+ if (components == Y_PLANE_COMPONENTS) {
+ if (layout.sampleIncrementInBits != 16) {
+ return BAD_VALUE;
+ }
+ if (layout.components[0].offsetInBits != 6) {
+ return BAD_VALUE;
+ }
+ dataY = (uint8_t *)pData + layout.offsetInBytes;
+ strideY = layout.strideInBytes;
+ } else if (components == CBCR_PLANE_COMPONENTS) {
+ if (layout.sampleIncrementInBits != 32) {
+ return BAD_VALUE;
+ }
+ for (const PlaneLayoutComponent &component : layout.components) {
+ if (component.type.value == int64_t(PlaneLayoutComponentType::CB) &&
+ component.offsetInBits != 6) {
+ return BAD_VALUE;
+ }
+ if (component.type.value == int64_t(PlaneLayoutComponentType::CR) &&
+ component.offsetInBits != 22) {
+ return BAD_VALUE;
+ }
+ }
+ dataCb = (uint8_t *)pData + layout.offsetInBytes;
+ dataCr = (uint8_t *)pData + layout.offsetInBytes + 2;
+ strideCbCr = layout.strideInBytes;
+ } else {
+ return BAD_VALUE;
+ }
+ }
+
+ outputImage->data = dataY;
+ outputImage->width = buffer->getWidth();
+ outputImage->height = buffer->getHeight();
+ outputImage->format = format;
+ outputImage->flexFormat =
+ static_cast<int>(AidlPixelFormat::YCBCR_P210);
+ outputImage->stride = strideY;
+
+ outputImage->dataCb = dataCb;
+ outputImage->dataCr = dataCr;
+ outputImage->chromaStride = strideCbCr;
+ outputImage->chromaStep = 4;
+ return OK;
+}
+
status_t lockImageFromBuffer(sp<GraphicBuffer> buffer, uint32_t inUsage,
const Rect& rect, int fenceFd, LockedImage* outputImage) {
ALOGV("%s: Try to lock the GraphicBuffer", __FUNCTION__);
@@ -581,10 +701,17 @@ status_t lockImageFromBuffer(sp<GraphicBuffer> buffer, uint32_t inUsage,
ALOGE("Lock buffer failed!");
return res;
}
- if (isPossibly10BitYUV(format)
- && OK == extractP010Gralloc4PlaneLayout(buffer, pData, format, outputImage)) {
- ALOGV("%s: Successfully locked the P010 image", __FUNCTION__);
- return OK;
+ if (isPossibly10BitYUV(format)) {
+ if (format == HAL_PIXEL_FORMAT_YCBCR_P010 &&
+ OK == extractP010Gralloc4PlaneLayout(buffer, pData, format, outputImage)) {
+ ALOGV("%s: Successfully locked the P010 image", __FUNCTION__);
+ return OK;
+ } else if ((format ==
+ static_cast<int>(AidlPixelFormat::YCBCR_P210)) &&
+ OK == extractP210Gralloc4PlaneLayout(buffer, pData, format, outputImage)) {
+ ALOGV("%s: Successfully locked the P210 image", __FUNCTION__);
+ return OK;
+ }
}
}