gralloc: Add support to getFormatLayout HAL API.
- Add API getFormatLayout which is required by camera
team to get information of all the planes present
during YUV format call.
- Refactor the function GetYUVPlaneInfo to give some
extra information of YUV plane.
CRs-Fixed: 2464961
Change-Id: Ib84fd340f8c8926867a6f7e2ec7c0074c4dada06
diff --git a/gralloc/QtiMapperExtensions.cpp b/gralloc/QtiMapperExtensions.cpp
index 56b747b..cace7ba 100644
--- a/gralloc/QtiMapperExtensions.cpp
+++ b/gralloc/QtiMapperExtensions.cpp
@@ -342,11 +342,46 @@
Return<void> QtiMapperExtensions::getFormatLayout(int32_t format, uint64_t usage, int32_t flags,
int32_t width, int32_t height,
getFormatLayout_cb hidl_cb) {
- ALOGD_IF(DEBUG, "%s: Input parameters - wxh: %dx%d usage: 0x%" PRIu64 " format: %d flags: %d",
- __FUNCTION__, width, height, usage, format, flags);
- auto err = Error::NONE;
+ ALOGD_IF(DEBUG, "%s: Input parameters - wxh: %dx%d usage: 0x%" PRIu64 " format: %d", __FUNCTION__,
+ width, height, usage, format);
+ auto err = Error::BAD_BUFFER;
hidl_vec<PlaneLayout> plane_info;
+ unsigned int alignedw = 0, alignedh = 0;
+ int plane_count = 0;
uint64_t size = 0;
+ int custom_format = gralloc::GetImplDefinedFormat(usage, format);
+ BufferInfo info(width, height, custom_format, usage);
+ gralloc::GetAlignedWidthAndHeight(info, &alignedw, &alignedh);
+ size = gralloc::GetSize(info, alignedw, alignedh);
+ ALOGD_IF(DEBUG, "%s: Aligned width and height - wxh: %ux%u custom_format = %d", __FUNCTION__,
+ alignedw, alignedh, custom_format);
+ if (gralloc::IsYuvFormat(custom_format)) {
+ gralloc::PlaneLayoutInfo yuv_plane_info[8] = {};
+ gralloc::GetYUVPlaneInfo(info, custom_format, alignedw, alignedh, flags, &plane_count,
+ yuv_plane_info);
+ ALOGD_IF(DEBUG, "%s: Number of plane - %d, custom_format - %d", __FUNCTION__, plane_count,
+ custom_format);
+ plane_info.resize(plane_count);
+ for (int i = 0; i < plane_count; i++) {
+ plane_info[i].component = yuv_plane_info[i].component;
+ plane_info[i].h_subsampling = yuv_plane_info[i].h_subsampling;
+ plane_info[i].v_subsampling = yuv_plane_info[i].v_subsampling;
+ plane_info[i].offset = yuv_plane_info[i].offset;
+ plane_info[i].pixel_increment = yuv_plane_info[i].step;
+ plane_info[i].stride = yuv_plane_info[i].stride;
+ plane_info[i].stride_bytes = yuv_plane_info[i].stride_bytes;
+ plane_info[i].scanlines = yuv_plane_info[i].scanlines;
+ plane_info[i].size = yuv_plane_info[i].size;
+ ALOGD_IF(DEBUG, "%s: plane info: component - %d", __FUNCTION__, plane_info[i].component);
+ ALOGD_IF(DEBUG, "h_subsampling - %u, v_subsampling - %u, offset - %u, pixel_increment - %d",
+ plane_info[i].h_subsampling, plane_info[i].v_subsampling, plane_info[i].offset,
+ plane_info[i].pixel_increment);
+ ALOGD_IF(DEBUG, "stride_pixel - %d, stride_bytes - %d, scanlines - %d, size - %u",
+ plane_info[i].stride, plane_info[i].stride_bytes, plane_info[i].scanlines,
+ plane_info[i].size);
+ }
+ err = Error::NONE;
+ }
hidl_cb(err, size, plane_info);
return Void();
}
diff --git a/gralloc/gr_utils.cpp b/gralloc/gr_utils.cpp
index 656ddec..9eca92d 100644
--- a/gralloc/gr_utils.cpp
+++ b/gralloc/gr_utils.cpp
@@ -360,14 +360,16 @@
return 0;
}
-void GetYuvUbwcSPPlaneInfo(uint64_t base, uint32_t width, uint32_t height, int color_format,
- struct android_ycbcr *ycbcr) {
+void GetYuvUbwcSPPlaneInfo(uint32_t width, uint32_t height, int color_format,
+ PlaneLayoutInfo *plane_info) {
// UBWC buffer has these 4 planes in the following sequence:
- // Y_Meta_Plane, Y_Plane, UV_Meta_Plane, UV_Plane
+ // Y_Plane, UV_Plane, Y_Meta_Plane, UV_Meta_Plane
unsigned int y_meta_stride, y_meta_height, y_meta_size;
unsigned int y_stride, y_height, y_size;
unsigned int c_meta_stride, c_meta_height, c_meta_size;
unsigned int alignment = 4096;
+ unsigned int c_stride, c_height, c_size;
+ uint64_t yOffset, cOffset, yMetaOffset, cMetaOffset;
y_meta_stride = VENUS_Y_META_STRIDE(color_format, INT(width));
y_meta_height = VENUS_Y_META_SCANLINES(color_format, INT(height));
@@ -381,47 +383,148 @@
c_meta_height = VENUS_UV_META_SCANLINES(color_format, INT(height));
c_meta_size = ALIGN((c_meta_stride * c_meta_height), alignment);
- ycbcr->y = reinterpret_cast<void *>(base + y_meta_size);
- ycbcr->cb = reinterpret_cast<void *>(base + y_meta_size + y_size + c_meta_size);
- ycbcr->cr = reinterpret_cast<void *>(base + y_meta_size + y_size + c_meta_size + 1);
- ycbcr->ystride = y_stride;
- ycbcr->cstride = VENUS_UV_STRIDE(color_format, INT(width));
+ c_stride = VENUS_UV_STRIDE(color_format, INT(width));
+ c_height = VENUS_UV_SCANLINES(color_format, INT(height));
+ c_size = ALIGN((c_stride * c_height), alignment);
+
+ yMetaOffset = 0;
+ yOffset = y_meta_size;
+ cMetaOffset = y_meta_size + y_size;
+ cOffset = y_meta_size + y_size + c_meta_size;
+
+ plane_info[0].component = (PlaneComponent)PLANE_COMPONENT_Y;
+ plane_info[0].offset = (uint32_t)yOffset;
+ plane_info[0].stride = static_cast<int32_t>(UINT(width));
+ plane_info[0].stride_bytes = static_cast<int32_t>(y_stride);
+ plane_info[0].scanlines = static_cast<int32_t>(y_height);
+ plane_info[0].size = static_cast<uint32_t>(y_size);
+
+ plane_info[1].component = (PlaneComponent)(PLANE_COMPONENT_Cb | PLANE_COMPONENT_Cr);
+ plane_info[1].offset = (uint32_t)cOffset;
+ plane_info[1].stride = static_cast<int32_t>(UINT(width));
+ plane_info[1].stride_bytes = static_cast<int32_t>(c_stride);
+ plane_info[1].scanlines = static_cast<int32_t>(c_height);
+ plane_info[1].size = static_cast<uint32_t>(c_size);
+
+ plane_info[2].component = (PlaneComponent)(PLANE_COMPONENT_META | PLANE_COMPONENT_Y);
+ plane_info[2].offset = (uint32_t)yMetaOffset;
+ plane_info[2].stride = static_cast<int32_t>(UINT(width));
+ plane_info[2].stride_bytes = static_cast<int32_t>(y_meta_stride);
+ plane_info[2].scanlines = static_cast<int32_t>(y_meta_height);
+ plane_info[2].size = static_cast<uint32_t>(y_meta_size);
+
+ plane_info[3].component =
+ (PlaneComponent)(PLANE_COMPONENT_META | PLANE_COMPONENT_Cb | PLANE_COMPONENT_Cr);
+ plane_info[3].offset = (uint32_t)cMetaOffset;
+ plane_info[3].stride = static_cast<int32_t>(UINT(width));
+ plane_info[3].stride_bytes = static_cast<int32_t>(c_meta_stride);
+ plane_info[3].scanlines = static_cast<int32_t>(c_meta_height);
+ plane_info[3].size = static_cast<uint32_t>(c_meta_size);
}
-void GetYuvUbwcInterlacedSPPlaneInfo(uint64_t base, uint32_t width, uint32_t height,
- int color_format, struct android_ycbcr ycbcr[2]) {
- unsigned int uv_stride, uv_height, uv_size;
- unsigned int alignment = 4096;
- uint64_t field_base;
-
+// This API gets information about 8 planes (Y_Plane, UV_Plane, Y_Meta_Plane, UV_Meta_Plane,
+// Y_Plane, UV_Plane, Y_Meta_Plane, UV_Meta_Plane) and it stores the
+// information in PlaneLayoutInfo array.
+void GetYuvUbwcInterlacedSPPlaneInfo(uint32_t width, uint32_t height,
+ PlaneLayoutInfo plane_info[8]) {
// UBWC interlaced has top-bottom field layout with each field as
- // 4-plane NV12_UBWC with width = image_width & height = image_height / 2.
- // Client passed ycbcr argument is ptr to struct android_ycbcr[2].
+ // 8-plane (including meta plane also) NV12_UBWC with width = image_width
+ // & height = image_height / 2.
+ // Client passed plane_info argument is ptr to struct PlaneLayoutInfo[8].
// Plane info to be filled for each field separately.
height = (height + 1) >> 1;
- uv_stride = VENUS_UV_STRIDE(color_format, INT(width));
- uv_height = VENUS_UV_SCANLINES(color_format, INT(height));
- uv_size = ALIGN((uv_stride * uv_height), alignment);
- field_base = base;
- GetYuvUbwcSPPlaneInfo(field_base, width, height, COLOR_FMT_NV12_UBWC, &ycbcr[0]);
+ GetYuvUbwcSPPlaneInfo(width, height, COLOR_FMT_NV12_UBWC, &plane_info[0]);
- memset(ycbcr[1].reserved, 0, sizeof(ycbcr[1].reserved));
- field_base = reinterpret_cast<uint64_t>(ycbcr[0].cb) + uv_size;
- GetYuvUbwcSPPlaneInfo(field_base, width, height, COLOR_FMT_NV12_UBWC, &ycbcr[1]);
+ GetYuvUbwcSPPlaneInfo(width, height, COLOR_FMT_NV12_UBWC, &plane_info[4]);
}
-void GetYuvSPPlaneInfo(uint64_t base, uint32_t width, uint32_t height, uint32_t bpp,
- struct android_ycbcr *ycbcr) {
- unsigned int ystride, cstride;
+// This API gets information about 2 planes (Y_Plane & UV_Plane)
+void GetYuvSPPlaneInfo(const BufferInfo &info, int format, uint32_t width, uint32_t height,
+ uint32_t bpp, PlaneLayoutInfo *plane_info) {
+ int unaligned_width = info.width;
+ int unaligned_height = info.height;
+ unsigned int y_stride = 0, y_height = 0, y_size = 0;
+ unsigned int c_stride = 0, c_height = 0, c_size = 0;
+ uint64_t yOffset, cOffset;
- ystride = cstride = UINT(width) * bpp;
- ycbcr->y = reinterpret_cast<void *>(base);
- ycbcr->cb = reinterpret_cast<void *>(base + ystride * UINT(height));
- ycbcr->cr = reinterpret_cast<void *>(base + ystride * UINT(height) + 1);
- ycbcr->ystride = ystride;
- ycbcr->cstride = cstride;
- ycbcr->chroma_step = 2 * bpp;
+ y_stride = c_stride = UINT(width) * bpp;
+ y_height = INT(height);
+ y_size = y_stride * y_height;
+ switch (format) {
+ case HAL_PIXEL_FORMAT_YCbCr_420_SP:
+ case HAL_PIXEL_FORMAT_YCrCb_420_SP:
+ c_size = (width * height) / 2 + 1;
+ c_height = height >> 1;
+ break;
+ case HAL_PIXEL_FORMAT_YCbCr_422_SP:
+ case HAL_PIXEL_FORMAT_YCrCb_422_SP:
+ if (unaligned_width & 1) {
+ ALOGE("width is odd for the YUV422_SP format");
+ return;
+ }
+ c_size = width * height;
+ c_height = height;
+ break;
+ case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
+ case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
+ c_height = VENUS_UV_SCANLINES(COLOR_FMT_NV12, height);
+ c_size = c_stride * c_height;
+ break;
+ case HAL_PIXEL_FORMAT_NV12_HEIF:
+ c_height = VENUS_UV_SCANLINES(COLOR_FMT_NV12_512, height);
+ c_size = c_stride * c_height;
+ break;
+ case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO:
+ y_size = ALIGN(width * height, 4096);
+ c_size = ALIGN(2 * ALIGN(unaligned_width / 2, 32) * ALIGN(unaligned_height / 2, 32), 4096);
+ break;
+ case HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS:
+ c_height = VENUS_UV_SCANLINES(COLOR_FMT_NV21, height);
+ c_size = c_stride * c_height;
+ break;
+ case HAL_PIXEL_FORMAT_NV21_ZSL:
+ c_size = (width * height) / 2;
+ c_height = height >> 1;
+ break;
+ case HAL_PIXEL_FORMAT_RAW16:
+ case HAL_PIXEL_FORMAT_Y16:
+ c_size = width * height;
+ c_height = height;
+ break;
+ case HAL_PIXEL_FORMAT_RAW10:
+ c_size = 0;
+ break;
+ case HAL_PIXEL_FORMAT_RAW8:
+ case HAL_PIXEL_FORMAT_Y8:
+ c_size = 0;
+ break;
+ case HAL_PIXEL_FORMAT_YCbCr_420_P010:
+ c_size = (width * height) + 1;
+ c_height = height;
+ break;
+ default:
+ break;
+ }
+
+ yOffset = 0;
+ cOffset = y_size;
+
+ plane_info[0].component = (PlaneComponent)PLANE_COMPONENT_Y;
+ plane_info[0].offset = (uint32_t)yOffset;
+ plane_info[0].step = 1;
+ plane_info[0].stride = static_cast<int32_t>(UINT(width));
+ plane_info[0].stride_bytes = static_cast<int32_t>(y_stride);
+ plane_info[0].scanlines = static_cast<int32_t>(y_height);
+ plane_info[0].size = static_cast<uint32_t>(y_size);
+
+ plane_info[1].component = (PlaneComponent)(PLANE_COMPONENT_Cb | PLANE_COMPONENT_Cr);
+ plane_info[1].offset = (uint32_t)cOffset;
+ plane_info[1].step = 2 * bpp;
+ plane_info[1].stride = static_cast<int32_t>(UINT(width));
+ plane_info[1].stride_bytes = static_cast<int32_t>(c_stride);
+ plane_info[1].scanlines = static_cast<int32_t>(c_height);
+ plane_info[1].size = static_cast<uint32_t>(c_size);
}
int GetYUVPlaneInfo(const private_handle_t *hnd, struct android_ycbcr ycbcr[2]) {
@@ -430,8 +533,11 @@
uint32_t height = UINT(hnd->height);
int format = hnd->format;
uint64_t usage = hnd->usage;
- unsigned int ystride, cstride;
- bool interlaced = false;
+ int32_t interlaced = 0;
+ int plane_count = 0;
+ int unaligned_width = INT(hnd->unaligned_width);
+ int unaligned_height = INT(hnd->unaligned_height);
+ BufferInfo info(unaligned_width, unaligned_height, format, usage);
memset(ycbcr->reserved, 0, sizeof(ycbcr->reserved));
@@ -452,102 +558,45 @@
int interlace_flag = 0;
if (getMetaData(const_cast<private_handle_t *>(hnd), GET_PP_PARAM_INTERLACED, &interlace_flag) ==
0) {
- interlaced = interlace_flag;
+ if (interlace_flag) {
+ interlaced = LAYOUT_INTERLACED_FLAG;
+ }
}
+ PlaneLayoutInfo plane_info[8] = {};
// Get the chroma offsets from the handle width/height. We take advantage
// of the fact the width _is_ the stride
- switch (format) {
- // Semiplanar
- case HAL_PIXEL_FORMAT_YCbCr_420_SP:
- case HAL_PIXEL_FORMAT_YCbCr_422_SP:
- case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
- case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
- case HAL_PIXEL_FORMAT_NV12_HEIF:
- // Same as YCbCr_420_SP_VENUS
- GetYuvSPPlaneInfo(hnd->base, width, height, 1, ycbcr);
- break;
-
- case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
- if (!interlaced) {
- GetYuvUbwcSPPlaneInfo(hnd->base, width, height, COLOR_FMT_NV12_UBWC, ycbcr);
- } else {
- GetYuvUbwcInterlacedSPPlaneInfo(hnd->base, width, height, COLOR_FMT_NV12_UBWC, ycbcr);
+ err = GetYUVPlaneInfo(info, format, width, height, interlaced, &plane_count, plane_info);
+ if (err == 0) {
+ if (interlaced && format == HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC) {
+ CopyPlaneLayoutInfotoAndroidYcbcr(hnd->base, plane_count, &plane_info[0], &ycbcr[0]);
+ unsigned int uv_stride, uv_height, uv_size;
+ unsigned int alignment = 4096;
+ uint64_t field_base;
+ height = (height + 1) >> 1;
+ uv_stride = VENUS_UV_STRIDE(COLOR_FMT_NV12_UBWC, INT(width));
+ uv_height = VENUS_UV_SCANLINES(COLOR_FMT_NV12_UBWC, INT(height));
+ uv_size = ALIGN((uv_stride * uv_height), alignment);
+ field_base = hnd->base + plane_info[1].offset + uv_size;
+ memset(ycbcr[1].reserved, 0, sizeof(ycbcr[1].reserved));
+ CopyPlaneLayoutInfotoAndroidYcbcr(field_base, plane_count, &plane_info[4], &ycbcr[1]);
+ } else {
+ CopyPlaneLayoutInfotoAndroidYcbcr(hnd->base, plane_count, plane_info, ycbcr);
+ switch (format) {
+ case HAL_PIXEL_FORMAT_YCrCb_420_SP:
+ case HAL_PIXEL_FORMAT_YCrCb_422_SP:
+ case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO:
+ case HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS:
+ case HAL_PIXEL_FORMAT_NV21_ZSL:
+ case HAL_PIXEL_FORMAT_RAW16:
+ case HAL_PIXEL_FORMAT_Y16:
+ case HAL_PIXEL_FORMAT_RAW10:
+ case HAL_PIXEL_FORMAT_RAW8:
+ case HAL_PIXEL_FORMAT_Y8:
+ std::swap(ycbcr->cb, ycbcr->cr);
}
- ycbcr->chroma_step = 2;
- break;
-
- case HAL_PIXEL_FORMAT_YCbCr_420_P010:
- GetYuvSPPlaneInfo(hnd->base, width, height, 2, ycbcr);
- break;
-
- case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC:
- GetYuvUbwcSPPlaneInfo(hnd->base, width, height, COLOR_FMT_NV12_BPP10_UBWC, ycbcr);
- ycbcr->chroma_step = 3;
- break;
-
- case HAL_PIXEL_FORMAT_YCbCr_420_P010_UBWC:
- GetYuvUbwcSPPlaneInfo(hnd->base, width, height, COLOR_FMT_P010_UBWC, ycbcr);
- ycbcr->chroma_step = 4;
- break;
-
- case HAL_PIXEL_FORMAT_YCbCr_420_P010_VENUS:
- ystride = VENUS_Y_STRIDE(COLOR_FMT_P010, width);
- cstride = VENUS_UV_STRIDE(COLOR_FMT_P010, width);
- ycbcr->y = reinterpret_cast<void *>(hnd->base);
- ycbcr->cb =
- reinterpret_cast<void *>(hnd->base + ystride * VENUS_Y_SCANLINES(COLOR_FMT_P010, height));
- ycbcr->cr = reinterpret_cast<void *>(hnd->base +
- ystride * VENUS_Y_SCANLINES(COLOR_FMT_P010, height) + 1);
- ycbcr->ystride = ystride;
- ycbcr->cstride = cstride;
- ycbcr->chroma_step = 4;
- break;
-
- case HAL_PIXEL_FORMAT_YCrCb_420_SP:
- case HAL_PIXEL_FORMAT_YCrCb_422_SP:
- case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO:
- case HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS:
- case HAL_PIXEL_FORMAT_NV21_ZSL:
- case HAL_PIXEL_FORMAT_RAW16:
- case HAL_PIXEL_FORMAT_Y16:
- case HAL_PIXEL_FORMAT_RAW10:
- case HAL_PIXEL_FORMAT_RAW8:
- case HAL_PIXEL_FORMAT_Y8:
- GetYuvSPPlaneInfo(hnd->base, width, height, 1, ycbcr);
- std::swap(ycbcr->cb, ycbcr->cr);
- break;
-
- // Planar
- case HAL_PIXEL_FORMAT_YV12:
- ystride = width;
- cstride = ALIGN(width / 2, 16);
- ycbcr->y = reinterpret_cast<void *>(hnd->base);
- ycbcr->cr = reinterpret_cast<void *>(hnd->base + ystride * height);
- ycbcr->cb = reinterpret_cast<void *>(hnd->base + ystride * height + cstride * height / 2);
- ycbcr->ystride = ystride;
- ycbcr->cstride = cstride;
- ycbcr->chroma_step = 1;
- break;
- case HAL_PIXEL_FORMAT_CbYCrY_422_I:
- ystride = width * 2;
- cstride = 0;
- ycbcr->y = reinterpret_cast<void *>(hnd->base);
- ycbcr->cr = NULL;
- ycbcr->cb = NULL;
- ycbcr->ystride = ystride;
- ycbcr->cstride = 0;
- ycbcr->chroma_step = 0;
- break;
- // Unsupported formats
- case HAL_PIXEL_FORMAT_YCbCr_422_I:
- case HAL_PIXEL_FORMAT_YCrCb_422_I:
- case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED:
- default:
- ALOGD("%s: Invalid format passed: 0x%x", __FUNCTION__, format);
- err = -EINVAL;
+ }
}
-
return err;
}
@@ -1217,4 +1266,298 @@
return IsYuvFormat(inputFormat) ? BUFFER_TYPE_VIDEO : BUFFER_TYPE_UI;
}
+int GetYUVPlaneInfo(const BufferInfo &info, int32_t format, int32_t width, int32_t height,
+ int32_t flags, int *plane_count, PlaneLayoutInfo *plane_info) {
+ int err = 0;
+ unsigned int y_stride, c_stride, y_height, c_height, y_size, c_size;
+ uint64_t yOffset, cOffset, crOffset, cbOffset;
+ int h_subsampling = 0, v_subsampling = 0;
+ switch (format) {
+ // Semiplanar
+ case HAL_PIXEL_FORMAT_YCbCr_420_SP:
+ case HAL_PIXEL_FORMAT_YCbCr_422_SP:
+ case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
+ case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
+ case HAL_PIXEL_FORMAT_NV12_HEIF: // Same as YCbCr_420_SP_VENUS
+ case HAL_PIXEL_FORMAT_YCrCb_420_SP:
+ case HAL_PIXEL_FORMAT_YCrCb_422_SP:
+ case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO:
+ case HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS:
+ case HAL_PIXEL_FORMAT_NV21_ZSL:
+ case HAL_PIXEL_FORMAT_RAW16:
+ case HAL_PIXEL_FORMAT_Y16:
+ case HAL_PIXEL_FORMAT_RAW10:
+ case HAL_PIXEL_FORMAT_RAW8:
+ case HAL_PIXEL_FORMAT_Y8:
+ *plane_count = 2;
+ GetYuvSPPlaneInfo(info, format, width, height, 1, plane_info);
+ GetYuvSubSamplingFactor(format, &h_subsampling, &v_subsampling);
+ plane_info[0].h_subsampling = 0;
+ plane_info[0].v_subsampling = 0;
+ plane_info[1].h_subsampling = h_subsampling;
+ plane_info[1].v_subsampling = v_subsampling;
+ break;
+
+ case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
+ GetYuvSubSamplingFactor(format, &h_subsampling, &v_subsampling);
+ if (flags & LAYOUT_INTERLACED_FLAG) {
+ *plane_count = 8;
+ GetYuvUbwcInterlacedSPPlaneInfo(width, height, plane_info);
+ plane_info[0].step = plane_info[4].step = 1;
+ plane_info[1].step = plane_info[5].step = 2;
+ plane_info[0].h_subsampling = plane_info[4].h_subsampling = 0;
+ plane_info[0].v_subsampling = plane_info[4].v_subsampling = 0;
+ plane_info[1].h_subsampling = plane_info[5].h_subsampling = h_subsampling;
+ plane_info[1].v_subsampling = plane_info[5].v_subsampling = v_subsampling;
+ plane_info[2].h_subsampling = plane_info[3].h_subsampling = 0;
+ plane_info[2].v_subsampling = plane_info[3].v_subsampling = 0;
+ plane_info[2].step = plane_info[3].step = 0;
+ plane_info[6].h_subsampling = plane_info[7].h_subsampling = 0;
+ plane_info[6].v_subsampling = plane_info[7].v_subsampling = 0;
+ plane_info[6].step = plane_info[7].step = 0;
+ } else {
+ *plane_count = 4;
+ GetYuvUbwcSPPlaneInfo(width, height, COLOR_FMT_NV12_UBWC, plane_info);
+ plane_info[0].h_subsampling = 0;
+ plane_info[0].v_subsampling = 0;
+ plane_info[0].step = 1;
+ plane_info[1].h_subsampling = h_subsampling;
+ plane_info[1].v_subsampling = v_subsampling;
+ plane_info[1].step = 2;
+ plane_info[2].h_subsampling = plane_info[3].h_subsampling = 0;
+ plane_info[2].v_subsampling = plane_info[3].v_subsampling = 0;
+ plane_info[2].step = plane_info[3].step = 0;
+ }
+ break;
+
+ case HAL_PIXEL_FORMAT_YCbCr_420_P010:
+ *plane_count = 2;
+ GetYuvSPPlaneInfo(info, format, width, height, 2, plane_info);
+ GetYuvSubSamplingFactor(format, &h_subsampling, &v_subsampling);
+ plane_info[0].h_subsampling = 0;
+ plane_info[0].v_subsampling = 0;
+ plane_info[1].h_subsampling = h_subsampling;
+ plane_info[1].v_subsampling = v_subsampling;
+ break;
+
+ case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC:
+ *plane_count = 4;
+ GetYuvUbwcSPPlaneInfo(width, height, COLOR_FMT_NV12_BPP10_UBWC, plane_info);
+ GetYuvSubSamplingFactor(format, &h_subsampling, &v_subsampling);
+ plane_info[0].h_subsampling = 0;
+ plane_info[0].v_subsampling = 0;
+ plane_info[1].step = 1;
+ plane_info[1].h_subsampling = h_subsampling;
+ plane_info[1].v_subsampling = v_subsampling;
+ plane_info[1].step = 3;
+ plane_info[2].h_subsampling = plane_info[3].h_subsampling = 0;
+ plane_info[2].v_subsampling = plane_info[3].v_subsampling = 0;
+ plane_info[2].step = plane_info[3].step = 0;
+ break;
+
+ case HAL_PIXEL_FORMAT_YCbCr_420_P010_UBWC:
+ *plane_count = 4;
+ GetYuvUbwcSPPlaneInfo(width, height, COLOR_FMT_P010_UBWC, plane_info);
+ GetYuvSubSamplingFactor(format, &h_subsampling, &v_subsampling);
+ plane_info[0].h_subsampling = 0;
+ plane_info[0].v_subsampling = 0;
+ plane_info[1].step = 1;
+ plane_info[1].h_subsampling = h_subsampling;
+ plane_info[1].v_subsampling = v_subsampling;
+ plane_info[1].step = 4;
+ plane_info[2].h_subsampling = plane_info[3].h_subsampling = 0;
+ plane_info[2].v_subsampling = plane_info[3].v_subsampling = 0;
+ plane_info[2].step = plane_info[3].step = 0;
+ break;
+
+ case HAL_PIXEL_FORMAT_YCbCr_420_P010_VENUS:
+ *plane_count = 2;
+ y_stride = VENUS_Y_STRIDE(COLOR_FMT_P010, width);
+ c_stride = VENUS_UV_STRIDE(COLOR_FMT_P010, width);
+ y_height = VENUS_Y_SCANLINES(COLOR_FMT_P010, height);
+ y_size = y_stride * y_height;
+ yOffset = 0;
+ cOffset = y_size;
+ c_height = VENUS_UV_SCANLINES(COLOR_FMT_P010, INT(height));
+ c_size = c_stride * c_height;
+ GetYuvSubSamplingFactor(format, &h_subsampling, &v_subsampling);
+
+ plane_info[0].component = (PlaneComponent)PLANE_COMPONENT_Y;
+ plane_info[0].offset = (uint32_t)yOffset;
+ plane_info[0].stride = static_cast<int32_t>(UINT(width));
+ plane_info[0].stride_bytes = static_cast<int32_t>(y_stride);
+ plane_info[0].scanlines = static_cast<int32_t>(y_height);
+ plane_info[0].size = static_cast<uint32_t>(y_size);
+ plane_info[0].step = 1;
+ plane_info[0].h_subsampling = 0;
+ plane_info[0].v_subsampling = 0;
+
+ plane_info[1].component = (PlaneComponent)(PLANE_COMPONENT_Cb | PLANE_COMPONENT_Cr);
+ plane_info[1].offset = (uint32_t)cOffset;
+ plane_info[1].stride = static_cast<int32_t>(UINT(width));
+ plane_info[1].stride_bytes = static_cast<int32_t>(c_stride);
+ plane_info[1].scanlines = static_cast<int32_t>(c_height);
+ plane_info[1].size = static_cast<uint32_t>(c_size);
+ plane_info[1].step = 4;
+ plane_info[1].h_subsampling = h_subsampling;
+ plane_info[1].v_subsampling = v_subsampling;
+ break;
+
+ // Planar
+ case HAL_PIXEL_FORMAT_YV12:
+ if ((info.width & 1) || (info.height & 1)) {
+ ALOGE("w or h is odd for the YV12 format");
+ err = -EINVAL;
+ return err;
+ }
+ *plane_count = 3;
+ y_stride = width;
+ c_stride = ALIGN(width / 2, 16);
+ y_height = UINT(height);
+ y_size = (y_stride * y_height);
+ height = height >> 1;
+ c_height = UINT(height);
+ c_size = (c_stride * c_height);
+ yOffset = 0;
+ crOffset = y_size;
+ cbOffset = (y_size + c_size);
+ GetYuvSubSamplingFactor(format, &h_subsampling, &v_subsampling);
+
+ plane_info[0].component = (PlaneComponent)PLANE_COMPONENT_Y;
+ plane_info[0].offset = (uint32_t)yOffset;
+ plane_info[0].stride = static_cast<int32_t>(UINT(width));
+ plane_info[0].stride_bytes = static_cast<int32_t>(y_stride);
+ plane_info[0].scanlines = static_cast<int32_t>(y_height);
+ plane_info[0].size = static_cast<uint32_t>(y_size);
+ plane_info[0].step = 1;
+ plane_info[0].h_subsampling = 0;
+ plane_info[0].v_subsampling = 0;
+
+ plane_info[1].component = (PlaneComponent)PLANE_COMPONENT_Cb;
+ plane_info[1].offset = (uint32_t)cbOffset;
+ plane_info[2].component = (PlaneComponent)PLANE_COMPONENT_Cr;
+ plane_info[2].offset = (uint32_t)crOffset;
+ for (int i = 1; i < 3; i++) {
+ plane_info[i].stride = static_cast<int32_t>(UINT(width));
+ plane_info[i].stride_bytes = static_cast<int32_t>(c_stride);
+ plane_info[i].scanlines = static_cast<int32_t>(c_height);
+ plane_info[i].size = static_cast<uint32_t>(c_size);
+ plane_info[i].step = 1;
+ plane_info[i].h_subsampling = h_subsampling;
+ plane_info[i].v_subsampling = v_subsampling;
+ }
+ break;
+ case HAL_PIXEL_FORMAT_CbYCrY_422_I:
+ if (info.width & 1) {
+ ALOGE("width is odd for the YUV422_SP format");
+ err = -EINVAL;
+ return err;
+ }
+ *plane_count = 1;
+ y_stride = width * 2;
+ y_height = UINT(height);
+ y_size = y_stride * y_height;
+ yOffset = 0;
+ plane_info[0].component = (PlaneComponent)PLANE_COMPONENT_Y;
+ plane_info[0].offset = (uint32_t)yOffset;
+ plane_info[0].stride = static_cast<int32_t>(UINT(width));
+ plane_info[0].stride_bytes = static_cast<int32_t>(y_stride);
+ plane_info[0].scanlines = static_cast<int32_t>(y_height);
+ plane_info[0].size = static_cast<uint32_t>(y_size);
+ plane_info[0].step = 1;
+ plane_info[0].h_subsampling = 0;
+ plane_info[0].v_subsampling = 0;
+ break;
+
+ // Unsupported formats
+ case HAL_PIXEL_FORMAT_YCbCr_422_I:
+ case HAL_PIXEL_FORMAT_YCrCb_422_I:
+ case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED:
+ default:
+ *plane_count = 0;
+ ALOGD("%s: Invalid format passed: 0x%x", __FUNCTION__, format);
+ err = -EINVAL;
+ }
+ return err;
+}
+
+void GetYuvSubSamplingFactor(int32_t format, int *h_subsampling, int *v_subsampling) {
+ switch (format) {
+ case HAL_PIXEL_FORMAT_YCbCr_420_SP:
+ case HAL_PIXEL_FORMAT_YCbCr_420_P010:
+ case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC:
+ case HAL_PIXEL_FORMAT_YCbCr_420_P010_UBWC:
+ case HAL_PIXEL_FORMAT_YCbCr_420_P010_VENUS:
+ case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
+ case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
+ case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO:
+ case HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS:
+ case HAL_PIXEL_FORMAT_YCrCb_420_SP:
+ case HAL_PIXEL_FORMAT_NV12_ENCODEABLE: // Same as YCbCr_420_SP_VENUS
+ case HAL_PIXEL_FORMAT_NV21_ZSL:
+ case HAL_PIXEL_FORMAT_YV12:
+ *h_subsampling = 1;
+ *v_subsampling = 1;
+ break;
+ case HAL_PIXEL_FORMAT_YCbCr_422_SP:
+ case HAL_PIXEL_FORMAT_YCrCb_422_SP:
+ case HAL_PIXEL_FORMAT_CbYCrY_422_I:
+ *h_subsampling = 1;
+ *v_subsampling = 0;
+ break;
+ case HAL_PIXEL_FORMAT_RAW16:
+ case HAL_PIXEL_FORMAT_Y16:
+ case HAL_PIXEL_FORMAT_RAW12:
+ case HAL_PIXEL_FORMAT_RAW10:
+ case HAL_PIXEL_FORMAT_Y8:
+ case HAL_PIXEL_FORMAT_BLOB:
+ case HAL_PIXEL_FORMAT_RAW_OPAQUE:
+ case HAL_PIXEL_FORMAT_NV12_HEIF:
+ default:
+ *h_subsampling = 0;
+ *v_subsampling = 0;
+ break;
+ }
+}
+
+void CopyPlaneLayoutInfotoAndroidYcbcr(uint64_t base, int plane_count, PlaneLayoutInfo *plane_info,
+ struct android_ycbcr *ycbcr) {
+ ycbcr->y = reinterpret_cast<void *>(base + plane_info[0].offset);
+ ycbcr->ystride = plane_info[0].stride_bytes;
+ if (plane_count == 1) {
+ ycbcr->cb = NULL;
+ ycbcr->cr = NULL;
+ ycbcr->cstride = 0;
+ ycbcr->chroma_step = 0;
+ } else if (plane_count == 2 || plane_count == 4 || plane_count == 8) {
+ /* For YUV semiplanar :-
+ * - In progressive & linear case plane count is 2 and plane_info[0] will
+ * contain info about Y plane and plane_info[1] will contain info about UV plane.
+ * - In progressive & compressed case plane count is 4 then plane_info[0] will
+ * contain info about Y plane and plane_info[1] will contain info about UV plane.
+ * Remaining two plane (plane_info[2] & plane_info[3]) contain info about the
+ * Y_Meta_Plane and UV_Meta_Plane.
+ * - In interlaced & compressed case plane count is 8 then plane_info[0], plane_info[1],
+ * plane_info[4] & plane_info[5] will contain info about Y_plane, UV_plane, Y_plane
+ * & UV_plane. Remaining plane will contain info about the meta planes. As in this case
+ * this API is called twice through GetYUVPlaneInfo() with address of plane_info[0] &
+ * plane_info[4], so this will calculate the information accordingly and will fill the
+ * ycbcr structure with interlaced plane info only.
+ */
+ ycbcr->cb = reinterpret_cast<void *>(base + plane_info[1].offset);
+ ycbcr->cr = reinterpret_cast<void *>(base + plane_info[1].offset + 1);
+ ycbcr->cstride = plane_info[1].stride_bytes;
+ ycbcr->chroma_step = plane_info[1].step;
+ } else if (plane_count == 3) {
+ /* For YUV planar :-
+ * Plane size is 3 and plane_info[0], plane_info[1], plane_info[2] will
+ * contain info about y_plane, cb_plane and cr_plane accordingly.
+ */
+ ycbcr->cb = reinterpret_cast<void *>(base + plane_info[1].offset);
+ ycbcr->cr = reinterpret_cast<void *>(base + plane_info[2].offset);
+ ycbcr->cstride = plane_info[1].stride_bytes;
+ ycbcr->chroma_step = plane_info[1].step;
+ }
+}
+
} // namespace gralloc
diff --git a/gralloc/gr_utils.h b/gralloc/gr_utils.h
index 309b8a7..8ecb90f 100644
--- a/gralloc/gr_utils.h
+++ b/gralloc/gr_utils.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011-2016,2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011-2016,2018-2019, The Linux Foundation. All rights reserved.
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -68,6 +68,63 @@
return (Type1)((x + (Type1)align - 1) & ~((Type1)align - 1));
}
+enum PlaneComponent {
+ /* luma */
+ PLANE_COMPONENT_Y = 1 << 0,
+ /* chroma blue */
+ PLANE_COMPONENT_Cb = 1 << 1,
+ /* chroma red */
+ PLANE_COMPONENT_Cr = 1 << 2,
+
+ /* red */
+ PLANE_COMPONENT_R = 1 << 10,
+ /* green */
+ PLANE_COMPONENT_G = 1 << 11,
+ /* blue */
+ PLANE_COMPONENT_B = 1 << 12,
+
+ /* alpha */
+ PLANE_COMPONENT_A = 1 << 20,
+
+ /* raw data plane */
+ PLANE_COMPONENT_RAW = 1 << 30,
+
+ /* meta information plane */
+ PLANE_COMPONENT_META = 1 << 31,
+};
+
+struct PlaneLayoutInfo {
+ /** Components represented the type of plane. */
+ PlaneComponent component;
+
+ /** horizontal subsampling. Must be a positive power of 2. */
+ uint32_t h_subsampling;
+
+ /** vertical subsampling. Must be a positive power of 2. */
+ uint32_t v_subsampling;
+
+ /** offset to the first byte of the top-left pixel of the plane
+ * and it is calculated from the start of the buffer.
+ * Add base of the handle with offset to get the first byte of the plane.
+ */
+ uint32_t offset;
+
+ /** step is the distance in bytes from one pixel value to the next. */
+ int32_t step;
+
+ /** stride of the plane in pixels */
+ int32_t stride;
+
+ /** stride of the plane in in bytes */
+ int32_t stride_bytes;
+
+ /** plane height or vertical stride */
+ int32_t scanlines;
+
+ /** size of the plane in bytes */
+ uint32_t size;
+};
+
bool IsYuvFormat(int format);
bool IsCompressedRGBFormat(int format);
bool IsUncompressedRGBFormat(int format);
@@ -85,6 +142,11 @@
void GetAlignedWidthAndHeight(const BufferInfo &d, unsigned int *aligned_w,
unsigned int *aligned_h);
int GetYUVPlaneInfo(const private_handle_t *hnd, struct android_ycbcr ycbcr[2]);
+int GetYUVPlaneInfo(const BufferInfo &info, int32_t format, int32_t width, int32_t height,
+ int32_t flags, int *plane_count, PlaneLayoutInfo plane_info[8]);
+void GetYuvSubSamplingFactor(int32_t format, int *h_subsampling, int *v_subsampling);
+void CopyPlaneLayoutInfotoAndroidYcbcr(uint64_t base, int plane_count, PlaneLayoutInfo *plane_info,
+ struct android_ycbcr *ycbcr);
int GetRgbDataAddress(private_handle_t *hnd, void **rgb_data);
bool IsUBwcFormat(int format);
bool IsUBwcSupported(int format);
@@ -92,12 +154,12 @@
bool IsUBwcEnabled(int format, uint64_t usage);
void GetYuvUBwcWidthAndHeight(int width, int height, int format, unsigned int *aligned_w,
unsigned int *aligned_h);
-void GetYuvSPPlaneInfo(uint64_t base, uint32_t width, uint32_t height, uint32_t bpp,
- struct android_ycbcr *ycbcr);
-void GetYuvUbwcSPPlaneInfo(uint64_t base, uint32_t width, uint32_t height, int color_format,
- struct android_ycbcr *ycbcr);
-void GetYuvUbwcInterlacedSPPlaneInfo(uint64_t base, uint32_t width, uint32_t height,
- int color_format, struct android_ycbcr ycbcr[2]);
+void GetYuvSPPlaneInfo(const BufferInfo &info, int format, uint32_t width, uint32_t height,
+ uint32_t bpp, PlaneLayoutInfo *plane_info);
+void GetYuvUbwcSPPlaneInfo(uint32_t width, uint32_t height, int color_format,
+ PlaneLayoutInfo *plane_info);
+void GetYuvUbwcInterlacedSPPlaneInfo(uint32_t width, uint32_t height,
+ PlaneLayoutInfo plane_info[8]);
void GetRgbUBwcBlockSize(uint32_t bpp, int *block_width, int *block_height);
unsigned int GetRgbUBwcMetaBufferSize(int width, int height, uint32_t bpp);
unsigned int GetUBwcSize(int width, int height, int format, unsigned int alignedw,