Merge "C2AllocationGralloc: refactor for media.c2 aidl" into main am: fdd1d5d685 am: 98fd188c91 am: 85c0fa7862 am: db60addc72 am: 4087fc849b
Original change: https://android-review.googlesource.com/c/platform/frameworks/av/+/2753645
Change-Id: I2fcd7f5831583f4e1b4289b2099d503c8b2b2fd8
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
diff --git a/media/codec2/vndk/C2AllocatorGralloc.cpp b/media/codec2/vndk/C2AllocatorGralloc.cpp
index 1ffa78f..9064eb9 100644
--- a/media/codec2/vndk/C2AllocatorGralloc.cpp
+++ b/media/codec2/vndk/C2AllocatorGralloc.cpp
@@ -327,6 +327,450 @@
return C2_OK;
}
+static c2_status_t PopulatePlaneLayout(
+ buffer_handle_t buffer,
+ const Rect &rect,
+ uint32_t format,
+ uint64_t grallocUsage,
+ uint32_t stride,
+ C2PlanarLayout *layout /* nonnull */, uint8_t **addr /* nonnull */) {
+ // 'NATIVE' on Android means LITTLE_ENDIAN
+ constexpr C2PlaneInfo::endianness_t kEndianness = C2PlaneInfo::NATIVE;
+
+ // Try to resolve IMPLEMENTATION_DEFINED format to accurate format if
+ // possible.
+ uint32_t fourCc;
+ if (format == HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED &&
+ !GraphicBufferMapper::get().getPixelFormatFourCC(buffer, &fourCc)) {
+ switch (fourCc) {
+ case DRM_FORMAT_XBGR8888:
+ format = static_cast<uint32_t>(PixelFormat4::RGBX_8888);
+ break;
+ case DRM_FORMAT_ABGR8888:
+ format = static_cast<uint32_t>(PixelFormat4::RGBA_8888);
+ break;
+ default:
+ break;
+ }
+ }
+
+ switch (format) {
+ case static_cast<uint32_t>(PixelFormat4::RGBA_1010102): {
+ // TRICKY: this is used for media as YUV444 in the case when it is queued directly to a
+ // Surface. In all other cases it is RGBA. We don't know which case it is here, so
+ // default to YUV for now.
+ void *pointer = nullptr;
+ // TODO: fence
+ status_t err = GraphicBufferMapper::get().lock(
+ const_cast<native_handle_t *>(buffer), grallocUsage, rect, &pointer);
+ if (err) {
+ ALOGE("failed transaction: lock(RGBA_1010102)");
+ return C2_CORRUPTED;
+ }
+ // treat as 32-bit values
+ addr[C2PlanarLayout::PLANE_Y] = (uint8_t *)pointer;
+ addr[C2PlanarLayout::PLANE_U] = (uint8_t *)pointer;
+ addr[C2PlanarLayout::PLANE_V] = (uint8_t *)pointer;
+ addr[C2PlanarLayout::PLANE_A] = (uint8_t *)pointer;
+ layout->type = C2PlanarLayout::TYPE_YUVA;
+ layout->numPlanes = 4;
+ layout->rootPlanes = 1;
+ layout->planes[C2PlanarLayout::PLANE_Y] = {
+ C2PlaneInfo::CHANNEL_Y, // channel
+ 4, // colInc
+ static_cast<int32_t>(4 * stride), // rowInc
+ 1, // mColSampling
+ 1, // mRowSampling
+ 32, // allocatedDepth
+ 10, // bitDepth
+ 10, // rightShift
+ C2PlaneInfo::LITTLE_END, // endianness
+ C2PlanarLayout::PLANE_Y, // rootIx
+ 0, // offset
+ };
+ layout->planes[C2PlanarLayout::PLANE_U] = {
+ C2PlaneInfo::CHANNEL_CB, // channel
+ 4, // colInc
+ static_cast<int32_t>(4 * stride), // rowInc
+ 1, // mColSampling
+ 1, // mRowSampling
+ 32, // allocatedDepth
+ 10, // bitDepth
+ 0, // rightShift
+ C2PlaneInfo::LITTLE_END, // endianness
+ C2PlanarLayout::PLANE_Y, // rootIx
+ 0, // offset
+ };
+ layout->planes[C2PlanarLayout::PLANE_V] = {
+ C2PlaneInfo::CHANNEL_CR, // channel
+ 4, // colInc
+ static_cast<int32_t>(4 * stride), // rowInc
+ 1, // mColSampling
+ 1, // mRowSampling
+ 32, // allocatedDepth
+ 10, // bitDepth
+ 20, // rightShift
+ C2PlaneInfo::LITTLE_END, // endianness
+ C2PlanarLayout::PLANE_Y, // rootIx
+ 0, // offset
+ };
+ layout->planes[C2PlanarLayout::PLANE_A] = {
+ C2PlaneInfo::CHANNEL_A, // channel
+ 4, // colInc
+ static_cast<int32_t>(4 * stride), // rowInc
+ 1, // mColSampling
+ 1, // mRowSampling
+ 32, // allocatedDepth
+ 2, // bitDepth
+ 30, // rightShift
+ C2PlaneInfo::LITTLE_END, // endianness
+ C2PlanarLayout::PLANE_Y, // rootIx
+ 0, // offset
+ };
+ break;
+ }
+
+ case static_cast<uint32_t>(PixelFormat4::RGBA_8888):
+ // TODO: alpha channel
+ // fall-through
+ case static_cast<uint32_t>(PixelFormat4::RGBX_8888): {
+ void *pointer = nullptr;
+ // TODO: fence
+ status_t err = GraphicBufferMapper::get().lock(
+ const_cast<native_handle_t*>(buffer), grallocUsage, rect, &pointer);
+ if (err) {
+ ALOGE("failed transaction: lock(RGBA_8888)");
+ return C2_CORRUPTED;
+ }
+ addr[C2PlanarLayout::PLANE_R] = (uint8_t *)pointer;
+ addr[C2PlanarLayout::PLANE_G] = (uint8_t *)pointer + 1;
+ addr[C2PlanarLayout::PLANE_B] = (uint8_t *)pointer + 2;
+ layout->type = C2PlanarLayout::TYPE_RGB;
+ layout->numPlanes = 3;
+ layout->rootPlanes = 1;
+ layout->planes[C2PlanarLayout::PLANE_R] = {
+ C2PlaneInfo::CHANNEL_R, // channel
+ 4, // colInc
+ static_cast<int32_t>(4 * stride), // rowInc
+ 1, // mColSampling
+ 1, // mRowSampling
+ 8, // allocatedDepth
+ 8, // bitDepth
+ 0, // rightShift
+ C2PlaneInfo::NATIVE, // endianness
+ C2PlanarLayout::PLANE_R, // rootIx
+ 0, // offset
+ };
+ layout->planes[C2PlanarLayout::PLANE_G] = {
+ C2PlaneInfo::CHANNEL_G, // channel
+ 4, // colInc
+ static_cast<int32_t>(4 * stride), // rowInc
+ 1, // mColSampling
+ 1, // mRowSampling
+ 8, // allocatedDepth
+ 8, // bitDepth
+ 0, // rightShift
+ C2PlaneInfo::NATIVE, // endianness
+ C2PlanarLayout::PLANE_R, // rootIx
+ 1, // offset
+ };
+ layout->planes[C2PlanarLayout::PLANE_B] = {
+ C2PlaneInfo::CHANNEL_B, // channel
+ 4, // colInc
+ static_cast<int32_t>(4 * stride), // rowInc
+ 1, // mColSampling
+ 1, // mRowSampling
+ 8, // allocatedDepth
+ 8, // bitDepth
+ 0, // rightShift
+ C2PlaneInfo::NATIVE, // endianness
+ C2PlanarLayout::PLANE_R, // rootIx
+ 2, // offset
+ };
+ break;
+ }
+
+ case static_cast<uint32_t>(PixelFormat4::BLOB): {
+ void *pointer = nullptr;
+ // TODO: fence
+ status_t err = GraphicBufferMapper::get().lock(
+ const_cast<native_handle_t*>(buffer), grallocUsage, rect, &pointer);
+ if (err) {
+ ALOGE("failed transaction: lock(BLOB)");
+ return C2_CORRUPTED;
+ }
+ *addr = (uint8_t *)pointer;
+ break;
+ }
+
+ case static_cast<uint32_t>(PixelFormat4::YCBCR_422_SP):
+ // fall-through
+ case static_cast<uint32_t>(PixelFormat4::YCRCB_420_SP):
+ // fall-through
+ case static_cast<uint32_t>(PixelFormat4::YCBCR_422_I):
+ // fall-through
+ case static_cast<uint32_t>(PixelFormat4::YCBCR_420_888):
+ // fall-through
+ case static_cast<uint32_t>(PixelFormat4::YV12): {
+ android_ycbcr ycbcrLayout;
+
+ status_t err = GraphicBufferMapper::get().lockYCbCr(
+ const_cast<native_handle_t*>(buffer), grallocUsage, rect, &ycbcrLayout);
+ if (err) {
+ ALOGE("failed transaction: lockYCbCr (err=%d)", err);
+ return C2_CORRUPTED;
+ }
+ if (!ycbcrLayout.y || !ycbcrLayout.cb || !ycbcrLayout.cr
+ || ycbcrLayout.ystride == 0
+ || ycbcrLayout.cstride == 0
+ || ycbcrLayout.chroma_step == 0) {
+ ALOGE("invalid layout: lockYCbCr (y=%s cb=%s cr=%s "
+ "ystride=%zu cstride=%zu chroma_step=%zu)",
+ ycbcrLayout.y ? "(non-null)" : "(null)",
+ ycbcrLayout.cb ? "(non-null)" : "(null)",
+ ycbcrLayout.cr ? "(non-null)" : "(null)",
+ ycbcrLayout.ystride, ycbcrLayout.cstride, ycbcrLayout.chroma_step);
+ return C2_CORRUPTED;
+ }
+
+ addr[C2PlanarLayout::PLANE_Y] = (uint8_t *)ycbcrLayout.y;
+ addr[C2PlanarLayout::PLANE_U] = (uint8_t *)ycbcrLayout.cb;
+ addr[C2PlanarLayout::PLANE_V] = (uint8_t *)ycbcrLayout.cr;
+ layout->type = C2PlanarLayout::TYPE_YUV;
+ layout->numPlanes = 3;
+ layout->rootPlanes = 3;
+ layout->planes[C2PlanarLayout::PLANE_Y] = {
+ C2PlaneInfo::CHANNEL_Y, // channel
+ 1, // colInc
+ (int32_t)ycbcrLayout.ystride, // rowInc
+ 1, // mColSampling
+ 1, // mRowSampling
+ 8, // allocatedDepth
+ 8, // bitDepth
+ 0, // rightShift
+ C2PlaneInfo::NATIVE, // endianness
+ C2PlanarLayout::PLANE_Y, // rootIx
+ 0, // offset
+ };
+ layout->planes[C2PlanarLayout::PLANE_U] = {
+ C2PlaneInfo::CHANNEL_CB, // channel
+ (int32_t)ycbcrLayout.chroma_step, // colInc
+ (int32_t)ycbcrLayout.cstride, // rowInc
+ 2, // mColSampling
+ 2, // mRowSampling
+ 8, // allocatedDepth
+ 8, // bitDepth
+ 0, // rightShift
+ C2PlaneInfo::NATIVE, // endianness
+ C2PlanarLayout::PLANE_U, // rootIx
+ 0, // offset
+ };
+ layout->planes[C2PlanarLayout::PLANE_V] = {
+ C2PlaneInfo::CHANNEL_CR, // channel
+ (int32_t)ycbcrLayout.chroma_step, // colInc
+ (int32_t)ycbcrLayout.cstride, // rowInc
+ 2, // mColSampling
+ 2, // mRowSampling
+ 8, // allocatedDepth
+ 8, // bitDepth
+ 0, // rightShift
+ C2PlaneInfo::NATIVE, // endianness
+ C2PlanarLayout::PLANE_V, // rootIx
+ 0, // offset
+ };
+ break;
+ }
+
+ case static_cast<uint32_t>(PixelFormat4::YCBCR_P010): {
+ // In Android T, P010 is relaxed to allow arbitrary stride for the Y and UV planes,
+ // try locking with the gralloc4 mapper first.
+ c2_status_t status = Gralloc4Mapper_lock(
+ const_cast<native_handle_t*>(buffer), grallocUsage, rect, layout, addr);
+ if (status == C2_OK) {
+ break;
+ }
+
+ void *pointer = nullptr;
+ status_t err = GraphicBufferMapper::get().lock(
+ const_cast<native_handle_t *>(buffer), grallocUsage, rect, &pointer);
+ if (err) {
+ ALOGE("failed transaction: lock(YCBCR_P010)");
+ return C2_CORRUPTED;
+ }
+ addr[C2PlanarLayout::PLANE_Y] = (uint8_t *)pointer;
+ addr[C2PlanarLayout::PLANE_U] = (uint8_t *)pointer + stride * 2 * rect.height();
+ addr[C2PlanarLayout::PLANE_V] = addr[C2PlanarLayout::PLANE_U] + 2;
+ layout->type = C2PlanarLayout::TYPE_YUV;
+ layout->numPlanes = 3;
+ layout->rootPlanes = 2;
+ layout->planes[C2PlanarLayout::PLANE_Y] = {
+ C2PlaneInfo::CHANNEL_Y, // channel
+ 2, // colInc
+ static_cast<int32_t>(2 * stride), // rowInc
+ 1, // mColSampling
+ 1, // mRowSampling
+ 16, // allocatedDepth
+ 10, // bitDepth
+ 6, // rightShift
+ kEndianness, // endianness
+ C2PlanarLayout::PLANE_Y, // rootIx
+ 0, // offset
+ };
+ layout->planes[C2PlanarLayout::PLANE_U] = {
+ C2PlaneInfo::CHANNEL_CB, // channel
+ 4, // colInc
+ static_cast<int32_t>(2 * stride), // rowInc
+ 2, // mColSampling
+ 2, // mRowSampling
+ 16, // allocatedDepth
+ 10, // bitDepth
+ 6, // rightShift
+ kEndianness, // endianness
+ C2PlanarLayout::PLANE_U, // rootIx
+ 0, // offset
+ };
+ layout->planes[C2PlanarLayout::PLANE_V] = {
+ C2PlaneInfo::CHANNEL_CR, // channel
+ 4, // colInc
+ static_cast<int32_t>(2 * stride), // rowInc
+ 2, // mColSampling
+ 2, // mRowSampling
+ 16, // allocatedDepth
+ 10, // bitDepth
+ 6, // rightShift
+ kEndianness, // endianness
+ C2PlanarLayout::PLANE_U, // rootIx
+ 2, // offset
+ };
+ break;
+ }
+
+ default: {
+ // We don't know what it is, let's try to lock it with gralloc4
+ android_ycbcr ycbcrLayout;
+ if (isAtLeastT()) {
+ c2_status_t status = Gralloc4Mapper_lock(
+ const_cast<native_handle_t*>(buffer), grallocUsage, rect, layout, addr);
+ if (status == C2_OK) {
+ break;
+ }
+ }
+
+ // fallback to lockYCbCr
+ status_t err = GraphicBufferMapper::get().lockYCbCr(
+ const_cast<native_handle_t*>(buffer), grallocUsage, rect, &ycbcrLayout);
+ if (err == OK && ycbcrLayout.y && ycbcrLayout.cb && ycbcrLayout.cr
+ && ycbcrLayout.ystride > 0
+ && ycbcrLayout.cstride > 0
+ && ycbcrLayout.chroma_step > 0) {
+ addr[C2PlanarLayout::PLANE_Y] = (uint8_t *)ycbcrLayout.y;
+ addr[C2PlanarLayout::PLANE_U] = (uint8_t *)ycbcrLayout.cb;
+ addr[C2PlanarLayout::PLANE_V] = (uint8_t *)ycbcrLayout.cr;
+ layout->type = C2PlanarLayout::TYPE_YUV;
+ layout->numPlanes = 3;
+ layout->rootPlanes = 3;
+ layout->planes[C2PlanarLayout::PLANE_Y] = {
+ C2PlaneInfo::CHANNEL_Y, // channel
+ 1, // colInc
+ (int32_t)ycbcrLayout.ystride, // rowInc
+ 1, // mColSampling
+ 1, // mRowSampling
+ 8, // allocatedDepth
+ 8, // bitDepth
+ 0, // rightShift
+ C2PlaneInfo::NATIVE, // endianness
+ C2PlanarLayout::PLANE_Y, // rootIx
+ 0, // offset
+ };
+ layout->planes[C2PlanarLayout::PLANE_U] = {
+ C2PlaneInfo::CHANNEL_CB, // channel
+ (int32_t)ycbcrLayout.chroma_step, // colInc
+ (int32_t)ycbcrLayout.cstride, // rowInc
+ 2, // mColSampling
+ 2, // mRowSampling
+ 8, // allocatedDepth
+ 8, // bitDepth
+ 0, // rightShift
+ C2PlaneInfo::NATIVE, // endianness
+ C2PlanarLayout::PLANE_U, // rootIx
+ 0, // offset
+ };
+ layout->planes[C2PlanarLayout::PLANE_V] = {
+ C2PlaneInfo::CHANNEL_CR, // channel
+ (int32_t)ycbcrLayout.chroma_step, // colInc
+ (int32_t)ycbcrLayout.cstride, // rowInc
+ 2, // mColSampling
+ 2, // mRowSampling
+ 8, // allocatedDepth
+ 8, // bitDepth
+ 0, // rightShift
+ C2PlaneInfo::NATIVE, // endianness
+ C2PlanarLayout::PLANE_V, // rootIx
+ 0, // offset
+ };
+ break;
+ }
+
+ // We really don't know what this is; lock the buffer and pass it through ---
+ // the client may know how to interpret it.
+
+ // unlock previous allocation if it was successful
+ if (err == OK) {
+ err = GraphicBufferMapper::get().unlock(buffer);
+ if (err) {
+ ALOGE("failed transaction: unlock");
+ return C2_CORRUPTED;
+ }
+ }
+
+ void *pointer = nullptr;
+ err = GraphicBufferMapper::get().lock(
+ const_cast<native_handle_t *>(buffer), grallocUsage, rect, &pointer);
+ if (err) {
+ ALOGE("failed transaction: lock(??? %x)", format);
+ return C2_CORRUPTED;
+ }
+ addr[0] = (uint8_t *)pointer;
+ layout->type = C2PlanarLayout::TYPE_UNKNOWN;
+ layout->numPlanes = 1;
+ layout->rootPlanes = 1;
+ layout->planes[0] = {
+ // TODO: CHANNEL_UNKNOWN?
+ C2PlaneInfo::channel_t(0xFF), // channel
+ 1, // colInc
+ int32_t(stride), // rowInc
+ 1, // mColSampling
+ 1, // mRowSampling
+ 8, // allocatedDepth
+ 8, // bitDepth
+ 0, // rightShift
+ C2PlaneInfo::NATIVE, // endianness
+ 0, // rootIx
+ 0, // offset
+ };
+ break;
+ }
+ }
+ return C2_OK;
+}
+
+static void HandleInterleavedPlanes(
+ C2PlanarLayout *layout /* nonnull */, uint8_t **addr /* nonnull */) {
+ if (layout->type == C2PlanarLayout::TYPE_YUV && layout->rootPlanes == 3) {
+ intptr_t uvOffset = addr[C2PlanarLayout::PLANE_V] - addr[C2PlanarLayout::PLANE_U];
+ intptr_t uvColInc = layout->planes[C2PlanarLayout::PLANE_U].colInc;
+ if (uvOffset > 0 && uvOffset < uvColInc) {
+ layout->rootPlanes = 2;
+ layout->planes[C2PlanarLayout::PLANE_V].rootIx = C2PlanarLayout::PLANE_U;
+ layout->planes[C2PlanarLayout::PLANE_V].offset = uvOffset;
+ } else if (uvOffset < 0 && uvOffset > -uvColInc) {
+ layout->rootPlanes = 2;
+ layout->planes[C2PlanarLayout::PLANE_U].rootIx = C2PlanarLayout::PLANE_V;
+ layout->planes[C2PlanarLayout::PLANE_U].offset = -uvOffset;
+ }
+ }
+}
+
} // unnamed namespace
@@ -488,440 +932,14 @@
mStride, generation, igbp_id, igbp_slot);
}
- // 'NATIVE' on Android means LITTLE_ENDIAN
- constexpr C2PlaneInfo::endianness_t kEndianness = C2PlaneInfo::NATIVE;
-
- // Try to resolve IMPLEMENTATION_DEFINED format to accurate format if
- // possible.
- uint32_t format = mFormat;
- uint32_t fourCc;
- if (format == HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED &&
- !GraphicBufferMapper::get().getPixelFormatFourCC(mBuffer, &fourCc)) {
- switch (fourCc) {
- case DRM_FORMAT_XBGR8888:
- format = static_cast<uint32_t>(PixelFormat4::RGBX_8888);
- break;
- case DRM_FORMAT_ABGR8888:
- format = static_cast<uint32_t>(PixelFormat4::RGBA_8888);
- break;
- default:
- break;
- }
- }
-
- switch (format) {
- case static_cast<uint32_t>(PixelFormat4::RGBA_1010102): {
- // TRICKY: this is used for media as YUV444 in the case when it is queued directly to a
- // Surface. In all other cases it is RGBA. We don't know which case it is here, so
- // default to YUV for now.
- void *pointer = nullptr;
- // TODO: fence
- status_t err = GraphicBufferMapper::get().lock(
- const_cast<native_handle_t *>(mBuffer), grallocUsage, rect, &pointer);
- if (err) {
- ALOGE("failed transaction: lock(RGBA_1010102)");
- return C2_CORRUPTED;
- }
- // treat as 32-bit values
- addr[C2PlanarLayout::PLANE_Y] = (uint8_t *)pointer;
- addr[C2PlanarLayout::PLANE_U] = (uint8_t *)pointer;
- addr[C2PlanarLayout::PLANE_V] = (uint8_t *)pointer;
- addr[C2PlanarLayout::PLANE_A] = (uint8_t *)pointer;
- layout->type = C2PlanarLayout::TYPE_YUVA;
- layout->numPlanes = 4;
- layout->rootPlanes = 1;
- layout->planes[C2PlanarLayout::PLANE_Y] = {
- C2PlaneInfo::CHANNEL_Y, // channel
- 4, // colInc
- static_cast<int32_t>(4 * mStride), // rowInc
- 1, // mColSampling
- 1, // mRowSampling
- 32, // allocatedDepth
- 10, // bitDepth
- 10, // rightShift
- C2PlaneInfo::LITTLE_END, // endianness
- C2PlanarLayout::PLANE_Y, // rootIx
- 0, // offset
- };
- layout->planes[C2PlanarLayout::PLANE_U] = {
- C2PlaneInfo::CHANNEL_CB, // channel
- 4, // colInc
- static_cast<int32_t>(4 * mStride), // rowInc
- 1, // mColSampling
- 1, // mRowSampling
- 32, // allocatedDepth
- 10, // bitDepth
- 0, // rightShift
- C2PlaneInfo::LITTLE_END, // endianness
- C2PlanarLayout::PLANE_Y, // rootIx
- 0, // offset
- };
- layout->planes[C2PlanarLayout::PLANE_V] = {
- C2PlaneInfo::CHANNEL_CR, // channel
- 4, // colInc
- static_cast<int32_t>(4 * mStride), // rowInc
- 1, // mColSampling
- 1, // mRowSampling
- 32, // allocatedDepth
- 10, // bitDepth
- 20, // rightShift
- C2PlaneInfo::LITTLE_END, // endianness
- C2PlanarLayout::PLANE_Y, // rootIx
- 0, // offset
- };
- layout->planes[C2PlanarLayout::PLANE_A] = {
- C2PlaneInfo::CHANNEL_A, // channel
- 4, // colInc
- static_cast<int32_t>(4 * mStride), // rowInc
- 1, // mColSampling
- 1, // mRowSampling
- 32, // allocatedDepth
- 2, // bitDepth
- 30, // rightShift
- C2PlaneInfo::LITTLE_END, // endianness
- C2PlanarLayout::PLANE_Y, // rootIx
- 0, // offset
- };
- break;
- }
-
- case static_cast<uint32_t>(PixelFormat4::RGBA_8888):
- // TODO: alpha channel
- // fall-through
- case static_cast<uint32_t>(PixelFormat4::RGBX_8888): {
- void *pointer = nullptr;
- // TODO: fence
- status_t err = GraphicBufferMapper::get().lock(
- const_cast<native_handle_t*>(mBuffer), grallocUsage, rect, &pointer);
- if (err) {
- ALOGE("failed transaction: lock(RGBA_8888)");
- return C2_CORRUPTED;
- }
- addr[C2PlanarLayout::PLANE_R] = (uint8_t *)pointer;
- addr[C2PlanarLayout::PLANE_G] = (uint8_t *)pointer + 1;
- addr[C2PlanarLayout::PLANE_B] = (uint8_t *)pointer + 2;
- layout->type = C2PlanarLayout::TYPE_RGB;
- layout->numPlanes = 3;
- layout->rootPlanes = 1;
- layout->planes[C2PlanarLayout::PLANE_R] = {
- C2PlaneInfo::CHANNEL_R, // channel
- 4, // colInc
- static_cast<int32_t>(4 * mStride), // rowInc
- 1, // mColSampling
- 1, // mRowSampling
- 8, // allocatedDepth
- 8, // bitDepth
- 0, // rightShift
- C2PlaneInfo::NATIVE, // endianness
- C2PlanarLayout::PLANE_R, // rootIx
- 0, // offset
- };
- layout->planes[C2PlanarLayout::PLANE_G] = {
- C2PlaneInfo::CHANNEL_G, // channel
- 4, // colInc
- static_cast<int32_t>(4 * mStride), // rowInc
- 1, // mColSampling
- 1, // mRowSampling
- 8, // allocatedDepth
- 8, // bitDepth
- 0, // rightShift
- C2PlaneInfo::NATIVE, // endianness
- C2PlanarLayout::PLANE_R, // rootIx
- 1, // offset
- };
- layout->planes[C2PlanarLayout::PLANE_B] = {
- C2PlaneInfo::CHANNEL_B, // channel
- 4, // colInc
- static_cast<int32_t>(4 * mStride), // rowInc
- 1, // mColSampling
- 1, // mRowSampling
- 8, // allocatedDepth
- 8, // bitDepth
- 0, // rightShift
- C2PlaneInfo::NATIVE, // endianness
- C2PlanarLayout::PLANE_R, // rootIx
- 2, // offset
- };
- break;
- }
-
- case static_cast<uint32_t>(PixelFormat4::BLOB): {
- void *pointer = nullptr;
- // TODO: fence
- status_t err = GraphicBufferMapper::get().lock(
- const_cast<native_handle_t*>(mBuffer), grallocUsage, rect, &pointer);
- if (err) {
- ALOGE("failed transaction: lock(BLOB)");
- return C2_CORRUPTED;
- }
- *addr = (uint8_t *)pointer;
- break;
- }
-
- case static_cast<uint32_t>(PixelFormat4::YCBCR_422_SP):
- // fall-through
- case static_cast<uint32_t>(PixelFormat4::YCRCB_420_SP):
- // fall-through
- case static_cast<uint32_t>(PixelFormat4::YCBCR_422_I):
- // fall-through
- case static_cast<uint32_t>(PixelFormat4::YCBCR_420_888):
- // fall-through
- case static_cast<uint32_t>(PixelFormat4::YV12): {
- android_ycbcr ycbcrLayout;
-
- status_t err = GraphicBufferMapper::get().lockYCbCr(
- const_cast<native_handle_t*>(mBuffer), grallocUsage, rect, &ycbcrLayout);
- if (err) {
- ALOGE("failed transaction: lockYCbCr (err=%d)", err);
- return C2_CORRUPTED;
- }
- if (!ycbcrLayout.y || !ycbcrLayout.cb || !ycbcrLayout.cr
- || ycbcrLayout.ystride == 0
- || ycbcrLayout.cstride == 0
- || ycbcrLayout.chroma_step == 0) {
- ALOGE("invalid layout: lockYCbCr (y=%s cb=%s cr=%s "
- "ystride=%zu cstride=%zu chroma_step=%zu)",
- ycbcrLayout.y ? "(non-null)" : "(null)",
- ycbcrLayout.cb ? "(non-null)" : "(null)",
- ycbcrLayout.cr ? "(non-null)" : "(null)",
- ycbcrLayout.ystride, ycbcrLayout.cstride, ycbcrLayout.chroma_step);
- return C2_CORRUPTED;
- }
-
- addr[C2PlanarLayout::PLANE_Y] = (uint8_t *)ycbcrLayout.y;
- addr[C2PlanarLayout::PLANE_U] = (uint8_t *)ycbcrLayout.cb;
- addr[C2PlanarLayout::PLANE_V] = (uint8_t *)ycbcrLayout.cr;
- layout->type = C2PlanarLayout::TYPE_YUV;
- layout->numPlanes = 3;
- layout->rootPlanes = 3;
- layout->planes[C2PlanarLayout::PLANE_Y] = {
- C2PlaneInfo::CHANNEL_Y, // channel
- 1, // colInc
- (int32_t)ycbcrLayout.ystride, // rowInc
- 1, // mColSampling
- 1, // mRowSampling
- 8, // allocatedDepth
- 8, // bitDepth
- 0, // rightShift
- C2PlaneInfo::NATIVE, // endianness
- C2PlanarLayout::PLANE_Y, // rootIx
- 0, // offset
- };
- layout->planes[C2PlanarLayout::PLANE_U] = {
- C2PlaneInfo::CHANNEL_CB, // channel
- (int32_t)ycbcrLayout.chroma_step, // colInc
- (int32_t)ycbcrLayout.cstride, // rowInc
- 2, // mColSampling
- 2, // mRowSampling
- 8, // allocatedDepth
- 8, // bitDepth
- 0, // rightShift
- C2PlaneInfo::NATIVE, // endianness
- C2PlanarLayout::PLANE_U, // rootIx
- 0, // offset
- };
- layout->planes[C2PlanarLayout::PLANE_V] = {
- C2PlaneInfo::CHANNEL_CR, // channel
- (int32_t)ycbcrLayout.chroma_step, // colInc
- (int32_t)ycbcrLayout.cstride, // rowInc
- 2, // mColSampling
- 2, // mRowSampling
- 8, // allocatedDepth
- 8, // bitDepth
- 0, // rightShift
- C2PlaneInfo::NATIVE, // endianness
- C2PlanarLayout::PLANE_V, // rootIx
- 0, // offset
- };
- break;
- }
-
- case static_cast<uint32_t>(PixelFormat4::YCBCR_P010): {
- // In Android T, P010 is relaxed to allow arbitrary stride for the Y and UV planes,
- // try locking with the gralloc4 mapper first.
- c2_status_t status = Gralloc4Mapper_lock(
- const_cast<native_handle_t*>(mBuffer), grallocUsage, rect, layout, addr);
- if (status == C2_OK) {
- break;
- }
-
- void *pointer = nullptr;
- status_t err = GraphicBufferMapper::get().lock(
- const_cast<native_handle_t *>(mBuffer), grallocUsage, rect, &pointer);
- if (err) {
- ALOGE("failed transaction: lock(YCBCR_P010)");
- return C2_CORRUPTED;
- }
- addr[C2PlanarLayout::PLANE_Y] = (uint8_t *)pointer;
- addr[C2PlanarLayout::PLANE_U] = (uint8_t *)pointer + mStride * 2 * rect.height();
- addr[C2PlanarLayout::PLANE_V] = addr[C2PlanarLayout::PLANE_U] + 2;
- layout->type = C2PlanarLayout::TYPE_YUV;
- layout->numPlanes = 3;
- layout->rootPlanes = 2;
- layout->planes[C2PlanarLayout::PLANE_Y] = {
- C2PlaneInfo::CHANNEL_Y, // channel
- 2, // colInc
- static_cast<int32_t>(2 * mStride), // rowInc
- 1, // mColSampling
- 1, // mRowSampling
- 16, // allocatedDepth
- 10, // bitDepth
- 6, // rightShift
- kEndianness, // endianness
- C2PlanarLayout::PLANE_Y, // rootIx
- 0, // offset
- };
- layout->planes[C2PlanarLayout::PLANE_U] = {
- C2PlaneInfo::CHANNEL_CB, // channel
- 4, // colInc
- static_cast<int32_t>(2 * mStride), // rowInc
- 2, // mColSampling
- 2, // mRowSampling
- 16, // allocatedDepth
- 10, // bitDepth
- 6, // rightShift
- kEndianness, // endianness
- C2PlanarLayout::PLANE_U, // rootIx
- 0, // offset
- };
- layout->planes[C2PlanarLayout::PLANE_V] = {
- C2PlaneInfo::CHANNEL_CR, // channel
- 4, // colInc
- static_cast<int32_t>(2 * mStride), // rowInc
- 2, // mColSampling
- 2, // mRowSampling
- 16, // allocatedDepth
- 10, // bitDepth
- 6, // rightShift
- kEndianness, // endianness
- C2PlanarLayout::PLANE_U, // rootIx
- 2, // offset
- };
- break;
- }
-
- default: {
- // We don't know what it is, let's try to lock it with gralloc4
- android_ycbcr ycbcrLayout;
- if (isAtLeastT()) {
- c2_status_t status = Gralloc4Mapper_lock(
- const_cast<native_handle_t*>(mBuffer), grallocUsage, rect, layout, addr);
- if (status == C2_OK) {
- break;
- }
- }
-
- // fallback to lockYCbCr
- status_t err = GraphicBufferMapper::get().lockYCbCr(
- const_cast<native_handle_t*>(mBuffer), grallocUsage, rect, &ycbcrLayout);
- if (err == OK && ycbcrLayout.y && ycbcrLayout.cb && ycbcrLayout.cr
- && ycbcrLayout.ystride > 0
- && ycbcrLayout.cstride > 0
- && ycbcrLayout.chroma_step > 0) {
- addr[C2PlanarLayout::PLANE_Y] = (uint8_t *)ycbcrLayout.y;
- addr[C2PlanarLayout::PLANE_U] = (uint8_t *)ycbcrLayout.cb;
- addr[C2PlanarLayout::PLANE_V] = (uint8_t *)ycbcrLayout.cr;
- layout->type = C2PlanarLayout::TYPE_YUV;
- layout->numPlanes = 3;
- layout->rootPlanes = 3;
- layout->planes[C2PlanarLayout::PLANE_Y] = {
- C2PlaneInfo::CHANNEL_Y, // channel
- 1, // colInc
- (int32_t)ycbcrLayout.ystride, // rowInc
- 1, // mColSampling
- 1, // mRowSampling
- 8, // allocatedDepth
- 8, // bitDepth
- 0, // rightShift
- C2PlaneInfo::NATIVE, // endianness
- C2PlanarLayout::PLANE_Y, // rootIx
- 0, // offset
- };
- layout->planes[C2PlanarLayout::PLANE_U] = {
- C2PlaneInfo::CHANNEL_CB, // channel
- (int32_t)ycbcrLayout.chroma_step, // colInc
- (int32_t)ycbcrLayout.cstride, // rowInc
- 2, // mColSampling
- 2, // mRowSampling
- 8, // allocatedDepth
- 8, // bitDepth
- 0, // rightShift
- C2PlaneInfo::NATIVE, // endianness
- C2PlanarLayout::PLANE_U, // rootIx
- 0, // offset
- };
- layout->planes[C2PlanarLayout::PLANE_V] = {
- C2PlaneInfo::CHANNEL_CR, // channel
- (int32_t)ycbcrLayout.chroma_step, // colInc
- (int32_t)ycbcrLayout.cstride, // rowInc
- 2, // mColSampling
- 2, // mRowSampling
- 8, // allocatedDepth
- 8, // bitDepth
- 0, // rightShift
- C2PlaneInfo::NATIVE, // endianness
- C2PlanarLayout::PLANE_V, // rootIx
- 0, // offset
- };
- break;
- }
-
- // We really don't know what this is; lock the buffer and pass it through ---
- // the client may know how to interpret it.
-
- // unlock previous allocation if it was successful
- if (err == OK) {
- err = GraphicBufferMapper::get().unlock(mBuffer);
- if (err) {
- ALOGE("failed transaction: unlock");
- return C2_CORRUPTED;
- }
- }
-
- void *pointer = nullptr;
- err = GraphicBufferMapper::get().lock(
- const_cast<native_handle_t *>(mBuffer), grallocUsage, rect, &pointer);
- if (err) {
- ALOGE("failed transaction: lock(??? %x)", mFormat);
- return C2_CORRUPTED;
- }
- addr[0] = (uint8_t *)pointer;
- layout->type = C2PlanarLayout::TYPE_UNKNOWN;
- layout->numPlanes = 1;
- layout->rootPlanes = 1;
- layout->planes[0] = {
- // TODO: CHANNEL_UNKNOWN?
- C2PlaneInfo::channel_t(0xFF), // channel
- 1, // colInc
- int32_t(mStride), // rowInc
- 1, // mColSampling
- 1, // mRowSampling
- 8, // allocatedDepth
- 8, // bitDepth
- 0, // rightShift
- C2PlaneInfo::NATIVE, // endianness
- 0, // rootIx
- 0, // offset
- };
- break;
- }
+ c2_status_t ret = PopulatePlaneLayout(
+ mBuffer, rect, mFormat, grallocUsage, mStride, layout, addr);
+ if (ret != C2_OK) {
+ return ret;
}
mLocked = true;
- // handle interleaved formats
- if (layout->type == C2PlanarLayout::TYPE_YUV && layout->rootPlanes == 3) {
- intptr_t uvOffset = addr[C2PlanarLayout::PLANE_V] - addr[C2PlanarLayout::PLANE_U];
- intptr_t uvColInc = layout->planes[C2PlanarLayout::PLANE_U].colInc;
- if (uvOffset > 0 && uvOffset < uvColInc) {
- layout->rootPlanes = 2;
- layout->planes[C2PlanarLayout::PLANE_V].rootIx = C2PlanarLayout::PLANE_U;
- layout->planes[C2PlanarLayout::PLANE_V].offset = uvOffset;
- } else if (uvOffset < 0 && uvOffset > -uvColInc) {
- layout->rootPlanes = 2;
- layout->planes[C2PlanarLayout::PLANE_U].rootIx = C2PlanarLayout::PLANE_V;
- layout->planes[C2PlanarLayout::PLANE_U].offset = -uvOffset;
- }
- }
+ HandleInterleavedPlanes(layout, addr);
ALOGV("C2AllocationGralloc::map: layout: type=%d numPlanes=%d rootPlanes=%d",
layout->type, layout->numPlanes, layout->rootPlanes);