diff --git a/libgralloc1/gr_buf_mgr.cpp b/libgralloc1/gr_buf_mgr.cpp index 743c1c22..7e0ba14b 100644 --- a/libgralloc1/gr_buf_mgr.cpp +++ b/libgralloc1/gr_buf_mgr.cpp @@ -771,6 +771,17 @@ gralloc1_error_t BufferManager::Perform(int operation, va_list args) { AllocateBuffer(descriptor, hnd, size); } break; + case GRALLOC1_MODULE_PERFORM_GET_INTERLACE_FLAG: { + private_handle_t *hnd = va_arg(args, private_handle_t *); + int *flag = va_arg(args, int *); + if (private_handle_t::validate(hnd) != 0) { + return GRALLOC1_ERROR_BAD_HANDLE; + } + if (getMetaData(hnd, GET_PP_PARAM_INTERLACED, flag) != 0) { + *flag = 0; + } + } break; + default: break; } diff --git a/libgralloc1/gr_utils.cpp b/libgralloc1/gr_utils.cpp index aee8c0d4..b3056e11 100644 --- a/libgralloc1/gr_utils.cpp +++ b/libgralloc1/gr_utils.cpp @@ -311,6 +311,28 @@ void GetYuvUbwcSPPlaneInfo(uint64_t base, uint32_t width, uint32_t height, ycbcr->cstride = VENUS_UV_STRIDE(color_format, INT(width)); } +void GetYuvUbwcInterlacedSPPlaneInfo(uint64_t base, uint32_t width, uint32_t height, + int color_format, struct android_ycbcr *ycbcr) { + unsigned int uv_stride, uv_height, uv_size; + unsigned int alignment = 4096; + uint64_t field_base; + + // 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]. + // 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]); + + field_base = reinterpret_cast(ycbcr[0].cb) + uv_size; + GetYuvUbwcSPPlaneInfo(field_base, width, height, COLOR_FMT_NV12_UBWC, &ycbcr[1]); +} + void GetYuvSPPlaneInfo(uint64_t base, uint32_t width, uint32_t height, uint32_t bpp, struct android_ycbcr *ycbcr) { unsigned int ystride, cstride; @@ -332,6 +354,7 @@ int GetYUVPlaneInfo(const private_handle_t *hnd, struct android_ycbcr *ycbcr) { gralloc1_producer_usage_t prod_usage = hnd->GetProducerUsage(); gralloc1_consumer_usage_t cons_usage = hnd->GetConsumerUsage(); unsigned int ystride, cstride; + bool interlaced = false; memset(ycbcr->reserved, 0, sizeof(ycbcr->reserved)); MetaData_t *metadata = reinterpret_cast(hnd->base_metadata); @@ -354,6 +377,11 @@ int GetYUVPlaneInfo(const private_handle_t *hnd, struct android_ycbcr *ycbcr) { GetAlignedWidthAndHeight(info, &width, &height); } + // Check metadata for interlaced content. + if (metadata && (metadata->operation & PP_PARAM_INTERLACED)) { + interlaced = metadata->interlaced ? true : false; + } + // Get the chroma offsets from the handle width/height. We take advantage // of the fact the width _is_ the stride switch (format) { @@ -371,7 +399,11 @@ int GetYUVPlaneInfo(const private_handle_t *hnd, struct android_ycbcr *ycbcr) { break; case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC: - GetYuvUbwcSPPlaneInfo(hnd->base, width, height, COLOR_FMT_NV12_UBWC, ycbcr); + if (!interlaced) { + GetYuvUbwcSPPlaneInfo(hnd->base, width, height, COLOR_FMT_NV12_UBWC, ycbcr); + } else { + GetYuvUbwcInterlacedSPPlaneInfo(hnd->base, width, height, COLOR_FMT_NV12_UBWC, ycbcr); + } ycbcr->chroma_step = 2; break; diff --git a/libgralloc1/gr_utils.h b/libgralloc1/gr_utils.h index aa66fd02..2a085392 100644 --- a/libgralloc1/gr_utils.h +++ b/libgralloc1/gr_utils.h @@ -83,6 +83,8 @@ void GetYuvSPPlaneInfo(uint64_t base, uint32_t width, uint32_t height, uint32_t 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); 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, diff --git a/libgralloc1/gralloc_priv.h b/libgralloc1/gralloc_priv.h index ba156b6f..1839d2f5 100644 --- a/libgralloc1/gralloc_priv.h +++ b/libgralloc1/gralloc_priv.h @@ -97,6 +97,7 @@ inline int roundUpToPageSize(int x) { #define GRALLOC_MODULE_PERFORM_SET_SINGLE_BUFFER_MODE 13 #define GRALLOC1_MODULE_PERFORM_GET_BUFFER_SIZE_AND_DIMENSIONS 14 #define GRALLOC1_MODULE_PERFORM_ALLOCATE_BUFFER 15 +#define GRALLOC1_MODULE_PERFORM_GET_INTERLACE_FLAG 16 // OEM specific HAL formats #define HAL_PIXEL_FORMAT_RGBA_5551 6