gralloc: Improve metadata fetching time

Add GetMetaDataValue to achieve similar performance and behaviour
as legacy qdMetadata. Update gralloc4 to use GetMetaDataInternal
so that shared logic is centralized where possible.

LNXDISPLAY-1606
CRs-Fixed: 3020633

Change-Id: If8d0fdff694136b9740148c319ff69fc432b5d78
diff --git a/gpu_tonemapper/Android.bp b/gpu_tonemapper/Android.bp
index df159d4..9249d82 100644
--- a/gpu_tonemapper/Android.bp
+++ b/gpu_tonemapper/Android.bp
@@ -12,6 +12,7 @@
         "libGLESv2",
         "libGLESv3",
         "libgrallocutils",
+        "libhidlbase",
         "libqdMetaData",
         "libui",
         "libutils",
diff --git a/gralloc/Android.bp b/gralloc/Android.bp
index 95b2af4..df27a54 100644
--- a/gralloc/Android.bp
+++ b/gralloc/Android.bp
@@ -16,6 +16,8 @@
     shared_libs: [
         "libqdMetaData",
         "libdl",
+        "libgralloctypes",
+        "libhidlbase",
         "android.hardware.graphics.common@1.2",
         "android.hardware.graphics.mapper@2.0",
         "android.hardware.graphics.mapper@2.1",
diff --git a/gralloc/QtiMapperExtensions.cpp b/gralloc/QtiMapperExtensions.cpp
index 0580fdb..156c59e 100644
--- a/gralloc/QtiMapperExtensions.cpp
+++ b/gralloc/QtiMapperExtensions.cpp
@@ -489,6 +489,7 @@
   _hidl_cb(error, out);
   return Void();
 }
+
 }  // namespace implementation
 }  // namespace V1_1
 }  // namespace mapperextensions
diff --git a/gralloc/gr_buf_mgr.cpp b/gralloc/gr_buf_mgr.cpp
index 9b6490c..393e6fc 100644
--- a/gralloc/gr_buf_mgr.cpp
+++ b/gralloc/gr_buf_mgr.cpp
@@ -46,7 +46,6 @@
 using aidl::android::hardware::graphics::common::Cta861_3;
 using aidl::android::hardware::graphics::common::Dataspace;
 using aidl::android::hardware::graphics::common::PlaneLayout;
-using aidl::android::hardware::graphics::common::PlaneLayoutComponent;
 using aidl::android::hardware::graphics::common::Rect;
 using aidl::android::hardware::graphics::common::Smpte2086;
 using aidl::android::hardware::graphics::common::StandardMetadataType;
@@ -58,61 +57,6 @@
                     descriptor.GetUsage());
 }
 
-static uint64_t getMetaDataSize(uint64_t reserved_region_size) {
-// Only include the reserved region size when using Metadata_t V2
-#ifndef METADATA_V2
-  reserved_region_size = 0;
-#endif
-  return static_cast<uint64_t>(ROUND_UP_PAGESIZE(sizeof(MetaData_t) + reserved_region_size));
-}
-
-static void unmapAndReset(private_handle_t *handle, uint64_t reserved_region_size = 0) {
-  if (private_handle_t::validate(handle) == 0 && handle->base_metadata) {
-    munmap(reinterpret_cast<void *>(handle->base_metadata), getMetaDataSize(reserved_region_size));
-    handle->base_metadata = 0;
-  }
-}
-
-static int validateAndMap(private_handle_t *handle, uint64_t reserved_region_size = 0) {
-  if (private_handle_t::validate(handle)) {
-    ALOGE("%s: Private handle is invalid - handle:%p", __func__, handle);
-    return -1;
-  }
-  if (handle->fd_metadata < 0) {
-    // Silently return, metadata cannot be used
-    return -1;
-  }
-
-  if (!handle->base_metadata) {
-    uint64_t size = getMetaDataSize(reserved_region_size);
-    void *base = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, handle->fd_metadata, 0);
-    if (base == reinterpret_cast<void *>(MAP_FAILED)) {
-      ALOGE("%s: metadata mmap failed - handle:%p fd: %d err: %s", __func__, handle,
-            handle->fd_metadata, strerror(errno));
-      return -1;
-    }
-    handle->base_metadata = (uintptr_t)base;
-#ifdef METADATA_V2
-    // The allocator process gets the reserved region size from the BufferDescriptor.
-    // When importing to another process, the reserved size is unknown until mapping the metadata,
-    // hence the re-mapping below
-    auto metadata = reinterpret_cast<MetaData_t *>(handle->base_metadata);
-    if (reserved_region_size == 0 && metadata->reservedSize) {
-      size = getMetaDataSize(metadata->reservedSize);
-      unmapAndReset(handle);
-      void *new_base = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, handle->fd_metadata, 0);
-      if (new_base == reinterpret_cast<void *>(MAP_FAILED)) {
-        ALOGE("%s: metadata mmap failed - handle:%p fd: %d err: %s", __func__, handle,
-              handle->fd_metadata, strerror(errno));
-        return -1;
-      }
-      handle->base_metadata = (uintptr_t)new_base;
-    }
-#endif
-  }
-  return 0;
-}
-
 static Error dataspaceToColorMetadata(Dataspace dataspace, ColorMetaData *color_metadata) {
   ColorMetaData out;
   uint32_t primaries = (uint32_t)dataspace & (uint32_t)Dataspace::STANDARD_MASK;
@@ -123,7 +67,7 @@
     case (uint32_t)Dataspace::STANDARD_BT709:
       out.colorPrimaries = ColorPrimaries_BT709_5;
       break;
-    // TODO(tbalacha): verify this is equivalent
+    // TODO(user): verify this is equivalent
     case (uint32_t)Dataspace::STANDARD_BT470M:
       out.colorPrimaries = ColorPrimaries_BT470_6M;
       break;
@@ -210,120 +154,6 @@
   color_metadata->range = out.range;
   return Error::NONE;
 }
-static Error colorMetadataToDataspace(ColorMetaData color_metadata, Dataspace *dataspace) {
-  Dataspace primaries, transfer, range = Dataspace::UNKNOWN;
-
-  switch (color_metadata.colorPrimaries) {
-    case ColorPrimaries_BT709_5:
-      primaries = Dataspace::STANDARD_BT709;
-      break;
-    // TODO(tbalacha): verify this is equivalent
-    case ColorPrimaries_BT470_6M:
-      primaries = Dataspace::STANDARD_BT470M;
-      break;
-    case ColorPrimaries_BT601_6_625:
-      primaries = Dataspace::STANDARD_BT601_625;
-      break;
-    case ColorPrimaries_BT601_6_525:
-      primaries = Dataspace::STANDARD_BT601_525;
-      break;
-    case ColorPrimaries_GenericFilm:
-      primaries = Dataspace::STANDARD_FILM;
-      break;
-    case ColorPrimaries_BT2020:
-      primaries = Dataspace::STANDARD_BT2020;
-      break;
-    case ColorPrimaries_AdobeRGB:
-      primaries = Dataspace::STANDARD_ADOBE_RGB;
-      break;
-    case ColorPrimaries_DCIP3:
-      primaries = Dataspace::STANDARD_DCI_P3;
-      break;
-    default:
-      return Error::UNSUPPORTED;
-      /*
-       ColorPrimaries_SMPTE_240M;
-       ColorPrimaries_SMPTE_ST428;
-       ColorPrimaries_EBU3213;
-      */
-  }
-
-  switch (color_metadata.transfer) {
-    case Transfer_sRGB:
-      transfer = Dataspace::TRANSFER_SRGB;
-      break;
-    case Transfer_Gamma2_2:
-      transfer = Dataspace::TRANSFER_GAMMA2_2;
-      break;
-    case Transfer_Gamma2_8:
-      transfer = Dataspace::TRANSFER_GAMMA2_8;
-      break;
-    case Transfer_SMPTE_170M:
-      transfer = Dataspace::TRANSFER_SMPTE_170M;
-      break;
-    case Transfer_Linear:
-      transfer = Dataspace::TRANSFER_LINEAR;
-      break;
-    case Transfer_HLG:
-      transfer = Dataspace::TRANSFER_HLG;
-      break;
-    default:
-      return Error::UNSUPPORTED;
-      /*
-      Transfer_SMPTE_240M
-      Transfer_Log
-      Transfer_Log_Sqrt
-      Transfer_XvYCC
-      Transfer_BT1361
-      Transfer_sYCC
-      Transfer_BT2020_2_1
-      Transfer_BT2020_2_2
-      Transfer_SMPTE_ST2084
-      Transfer_ST_428
-      */
-  }
-
-  switch (color_metadata.range) {
-    case Range_Full:
-      range = Dataspace::RANGE_FULL;
-      break;
-    case Range_Limited:
-      range = Dataspace::RANGE_LIMITED;
-      break;
-    case Range_Extended:
-      range = Dataspace::RANGE_EXTENDED;
-      break;
-    default:
-      return Error::UNSUPPORTED;
-  }
-
-  *dataspace = (Dataspace)((uint32_t)primaries | (uint32_t)transfer | (uint32_t)range);
-  return Error::NONE;
-}
-
-#ifdef QTI_COLORSPACE
-static Error getColorSpaceFromMetaData(ColorMetaData color_metadata, uint32_t *color_space) {
-  Error err = Error::NONE;
-  switch (color_metadata.colorPrimaries) {
-    case ColorPrimaries_BT709_5:
-      *color_space = HAL_CSC_ITU_R_709;
-      break;
-    case ColorPrimaries_BT601_6_525:
-    case ColorPrimaries_BT601_6_625:
-      *color_space = ((color_metadata.range) ? HAL_CSC_ITU_R_601_FR : HAL_CSC_ITU_R_601);
-      break;
-    case ColorPrimaries_BT2020:
-      *color_space = (color_metadata.range) ? HAL_CSC_ITU_R_2020_FR : HAL_CSC_ITU_R_2020;
-      break;
-    default:
-      err = Error::UNSUPPORTED;
-      *color_space = 0;
-      ALOGW("Unknown Color primary = %d", color_metadata.colorPrimaries);
-      break;
-  }
-  return err;
-}
-#endif
 
 #ifdef QTI_YUV_PLANE_INFO
 static Error getYUVPlaneInfo(const private_handle_t *hnd, struct android_ycbcr ycbcr[2]) {
@@ -398,410 +228,6 @@
 }
 #endif
 
-static Error getComponentSizeAndOffset(int32_t format, PlaneLayoutComponent &comp) {
-  switch (format) {
-    case static_cast<int32_t>(HAL_PIXEL_FORMAT_RGBA_8888):
-    case static_cast<int32_t>(HAL_PIXEL_FORMAT_RGBX_8888):
-    case static_cast<int32_t>(HAL_PIXEL_FORMAT_RGB_888):
-      comp.sizeInBits = 8;
-      if (comp.type.value == android::gralloc4::PlaneLayoutComponentType_R.value) {
-        comp.offsetInBits = 0;
-      } else if (comp.type.value == android::gralloc4::PlaneLayoutComponentType_G.value) {
-        comp.offsetInBits = 8;
-      } else if (comp.type.value == android::gralloc4::PlaneLayoutComponentType_B.value) {
-        comp.offsetInBits = 16;
-      } else if (comp.type.value == android::gralloc4::PlaneLayoutComponentType_A.value &&
-                 format != HAL_PIXEL_FORMAT_RGB_888) {
-        comp.offsetInBits = 24;
-      } else {
-        return Error::BAD_VALUE;
-      }
-      break;
-    case static_cast<int32_t>(HAL_PIXEL_FORMAT_RGB_565):
-      if (comp.type.value == android::gralloc4::PlaneLayoutComponentType_R.value) {
-        comp.offsetInBits = 0;
-        comp.sizeInBits = 5;
-      } else if (comp.type.value == android::gralloc4::PlaneLayoutComponentType_G.value) {
-        comp.offsetInBits = 5;
-        comp.sizeInBits = 6;
-      } else if (comp.type.value == android::gralloc4::PlaneLayoutComponentType_B.value) {
-        comp.offsetInBits = 11;
-        comp.sizeInBits = 5;
-      } else {
-        return Error::BAD_VALUE;
-      }
-      break;
-    case static_cast<int32_t>(HAL_PIXEL_FORMAT_BGR_565):
-      if (comp.type.value == android::gralloc4::PlaneLayoutComponentType_R.value) {
-        comp.offsetInBits = 11;
-        comp.sizeInBits = 5;
-      } else if (comp.type.value == android::gralloc4::PlaneLayoutComponentType_G.value) {
-        comp.offsetInBits = 5;
-        comp.sizeInBits = 6;
-      } else if (comp.type.value == android::gralloc4::PlaneLayoutComponentType_B.value) {
-        comp.offsetInBits = 0;
-        comp.sizeInBits = 5;
-      } else {
-        return Error::BAD_VALUE;
-      }
-      break;
-    case static_cast<int32_t>(HAL_PIXEL_FORMAT_BGRA_8888):
-    case static_cast<int32_t>(HAL_PIXEL_FORMAT_BGRX_8888):
-    case static_cast<int32_t>(HAL_PIXEL_FORMAT_BGR_888):
-      comp.sizeInBits = 8;
-      if (comp.type.value == android::gralloc4::PlaneLayoutComponentType_R.value) {
-        comp.offsetInBits = 16;
-      } else if (comp.type.value == android::gralloc4::PlaneLayoutComponentType_G.value) {
-        comp.offsetInBits = 8;
-      } else if (comp.type.value == android::gralloc4::PlaneLayoutComponentType_B.value) {
-        comp.offsetInBits = 0;
-      } else if (comp.type.value == android::gralloc4::PlaneLayoutComponentType_A.value &&
-                 format != HAL_PIXEL_FORMAT_BGR_888) {
-        comp.offsetInBits = 24;
-      } else {
-        return Error::BAD_VALUE;
-      }
-      break;
-    case static_cast<int32_t>(HAL_PIXEL_FORMAT_RGBA_5551):
-      if (comp.type.value == android::gralloc4::PlaneLayoutComponentType_R.value) {
-        comp.sizeInBits = 5;
-        comp.offsetInBits = 0;
-      } else if (comp.type.value == android::gralloc4::PlaneLayoutComponentType_G.value) {
-        comp.sizeInBits = 5;
-        comp.offsetInBits = 5;
-      } else if (comp.type.value == android::gralloc4::PlaneLayoutComponentType_B.value) {
-        comp.sizeInBits = 5;
-        comp.offsetInBits = 10;
-      } else if (comp.type.value == android::gralloc4::PlaneLayoutComponentType_A.value) {
-        comp.sizeInBits = 1;
-        comp.offsetInBits = 15;
-      } else {
-        return Error::BAD_VALUE;
-      }
-      break;
-    case static_cast<int32_t>(HAL_PIXEL_FORMAT_RGBA_4444):
-      if (comp.type.value == android::gralloc4::PlaneLayoutComponentType_R.value) {
-        comp.sizeInBits = 4;
-        comp.offsetInBits = 0;
-      } else if (comp.type.value == android::gralloc4::PlaneLayoutComponentType_G.value) {
-        comp.sizeInBits = 4;
-        comp.offsetInBits = 4;
-      } else if (comp.type.value == android::gralloc4::PlaneLayoutComponentType_B.value) {
-        comp.sizeInBits = 4;
-        comp.offsetInBits = 8;
-      } else if (comp.type.value == android::gralloc4::PlaneLayoutComponentType_A.value) {
-        comp.sizeInBits = 4;
-        comp.offsetInBits = 12;
-      } else {
-        return Error::BAD_VALUE;
-      }
-      break;
-    case static_cast<int32_t>(HAL_PIXEL_FORMAT_R_8):
-    case static_cast<int32_t>(HAL_PIXEL_FORMAT_RG_88):
-      comp.sizeInBits = 8;
-      if (comp.type.value == android::gralloc4::PlaneLayoutComponentType_R.value) {
-        comp.offsetInBits = 0;
-      } else if (comp.type.value == android::gralloc4::PlaneLayoutComponentType_G.value &&
-                 format != HAL_PIXEL_FORMAT_R_8) {
-        comp.offsetInBits = 8;
-      } else {
-        return Error::BAD_VALUE;
-      }
-      break;
-    case static_cast<int32_t>(HAL_PIXEL_FORMAT_RGBA_1010102):
-    case static_cast<int32_t>(HAL_PIXEL_FORMAT_RGBX_1010102):
-      if (comp.type.value == android::gralloc4::PlaneLayoutComponentType_R.value) {
-        comp.sizeInBits = 10;
-        comp.offsetInBits = 0;
-      } else if (comp.type.value == android::gralloc4::PlaneLayoutComponentType_G.value) {
-        comp.sizeInBits = 10;
-        comp.offsetInBits = 10;
-      } else if (comp.type.value == android::gralloc4::PlaneLayoutComponentType_B.value) {
-        comp.sizeInBits = 10;
-        comp.offsetInBits = 20;
-      } else if (comp.type.value == android::gralloc4::PlaneLayoutComponentType_A.value) {
-        comp.sizeInBits = 2;
-        comp.offsetInBits = 30;
-      } else {
-        return Error::BAD_VALUE;
-      }
-      break;
-    case static_cast<int32_t>(HAL_PIXEL_FORMAT_ARGB_2101010):
-    case static_cast<int32_t>(HAL_PIXEL_FORMAT_XRGB_2101010):
-      if (comp.type.value == android::gralloc4::PlaneLayoutComponentType_R.value) {
-        comp.sizeInBits = 10;
-        comp.offsetInBits = 2;
-      } else if (comp.type.value == android::gralloc4::PlaneLayoutComponentType_G.value) {
-        comp.sizeInBits = 10;
-        comp.offsetInBits = 12;
-      } else if (comp.type.value == android::gralloc4::PlaneLayoutComponentType_B.value) {
-        comp.sizeInBits = 10;
-        comp.offsetInBits = 22;
-      } else if (comp.type.value == android::gralloc4::PlaneLayoutComponentType_A.value) {
-        comp.sizeInBits = 2;
-        comp.offsetInBits = 0;
-      } else {
-        return Error::BAD_VALUE;
-      }
-      break;
-    case static_cast<int32_t>(HAL_PIXEL_FORMAT_BGRA_1010102):
-    case static_cast<int32_t>(HAL_PIXEL_FORMAT_BGRX_1010102):
-      if (comp.type.value == android::gralloc4::PlaneLayoutComponentType_R.value) {
-        comp.sizeInBits = 10;
-        comp.offsetInBits = 20;
-      } else if (comp.type.value == android::gralloc4::PlaneLayoutComponentType_G.value) {
-        comp.sizeInBits = 10;
-        comp.offsetInBits = 10;
-      } else if (comp.type.value == android::gralloc4::PlaneLayoutComponentType_B.value) {
-        comp.sizeInBits = 10;
-        comp.offsetInBits = 0;
-      } else if (comp.type.value == android::gralloc4::PlaneLayoutComponentType_A.value) {
-        comp.sizeInBits = 2;
-        comp.offsetInBits = 30;
-      } else {
-        return Error::BAD_VALUE;
-      }
-      break;
-    case static_cast<int32_t>(HAL_PIXEL_FORMAT_ABGR_2101010):
-    case static_cast<int32_t>(HAL_PIXEL_FORMAT_XBGR_2101010):
-      if (comp.type.value == android::gralloc4::PlaneLayoutComponentType_R.value) {
-        comp.sizeInBits = 10;
-        comp.offsetInBits = 22;
-      } else if (comp.type.value == android::gralloc4::PlaneLayoutComponentType_G.value) {
-        comp.sizeInBits = 10;
-        comp.offsetInBits = 12;
-      } else if (comp.type.value == android::gralloc4::PlaneLayoutComponentType_B.value) {
-        comp.sizeInBits = 10;
-        comp.offsetInBits = 2;
-      } else if (comp.type.value == android::gralloc4::PlaneLayoutComponentType_A.value) {
-        comp.sizeInBits = 2;
-        comp.offsetInBits = 0;
-      } else {
-        return Error::BAD_VALUE;
-      }
-      break;
-    case static_cast<int32_t>(HAL_PIXEL_FORMAT_RGBA_FP16):
-      if (comp.type.value == android::gralloc4::PlaneLayoutComponentType_R.value) {
-        comp.sizeInBits = 16;
-        comp.offsetInBits = 0;
-      } else if (comp.type.value == android::gralloc4::PlaneLayoutComponentType_G.value) {
-        comp.sizeInBits = 16;
-        comp.offsetInBits = 16;
-      } else if (comp.type.value == android::gralloc4::PlaneLayoutComponentType_B.value) {
-        comp.sizeInBits = 16;
-        comp.offsetInBits = 32;
-      } else if (comp.type.value == android::gralloc4::PlaneLayoutComponentType_A.value) {
-        comp.sizeInBits = 16;
-        comp.offsetInBits = 48;
-      } else {
-        return Error::BAD_VALUE;
-      }
-      break;
-    case static_cast<int32_t>(HAL_PIXEL_FORMAT_YCbCr_420_SP):
-    case static_cast<int32_t>(HAL_PIXEL_FORMAT_YCbCr_422_SP):
-    case static_cast<int32_t>(HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS):
-    case static_cast<int32_t>(HAL_PIXEL_FORMAT_NV12_ENCODEABLE):
-      comp.sizeInBits = 8;
-      if (comp.type.value == android::gralloc4::PlaneLayoutComponentType_Y.value ||
-          comp.type.value == android::gralloc4::PlaneLayoutComponentType_CB.value) {
-        comp.offsetInBits = 0;
-      } else if (comp.type.value == android::gralloc4::PlaneLayoutComponentType_CR.value) {
-        comp.offsetInBits = 8;
-      } else {
-        return Error::BAD_VALUE;
-      }
-      break;
-    case static_cast<int32_t>(HAL_PIXEL_FORMAT_YCrCb_420_SP):
-    case static_cast<int32_t>(HAL_PIXEL_FORMAT_YCrCb_422_SP):
-    case static_cast<int32_t>(HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO):
-    case static_cast<int32_t>(HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS):
-    case static_cast<int32_t>(HAL_PIXEL_FORMAT_NV21_ZSL):
-      comp.sizeInBits = 8;
-      if (comp.type.value == android::gralloc4::PlaneLayoutComponentType_Y.value ||
-          comp.type.value == android::gralloc4::PlaneLayoutComponentType_CR.value) {
-        comp.offsetInBits = 0;
-      } else if (comp.type.value == android::gralloc4::PlaneLayoutComponentType_CB.value) {
-        comp.offsetInBits = 8;
-      } else {
-        return Error::BAD_VALUE;
-      }
-      break;
-    case static_cast<int32_t>(HAL_PIXEL_FORMAT_Y16):
-      if (comp.type.value == android::gralloc4::PlaneLayoutComponentType_Y.value) {
-        comp.offsetInBits = 0;
-        comp.sizeInBits = 16;
-      } else {
-        return Error::BAD_VALUE;
-      }
-      break;
-    case static_cast<int32_t>(HAL_PIXEL_FORMAT_YV12):
-      if (comp.type.value == android::gralloc4::PlaneLayoutComponentType_Y.value ||
-          comp.type.value == android::gralloc4::PlaneLayoutComponentType_CB.value ||
-          comp.type.value == android::gralloc4::PlaneLayoutComponentType_CR.value) {
-        comp.offsetInBits = 0;
-        comp.sizeInBits = 8;
-      } else {
-        return Error::BAD_VALUE;
-      }
-      break;
-    case static_cast<int32_t>(HAL_PIXEL_FORMAT_Y8):
-      if (comp.type.value == android::gralloc4::PlaneLayoutComponentType_Y.value) {
-        comp.offsetInBits = 0;
-        comp.sizeInBits = 8;
-      } else {
-        return Error::BAD_VALUE;
-      }
-      break;
-    case static_cast<int32_t>(HAL_PIXEL_FORMAT_YCbCr_420_P010):
-      if (comp.type.value == android::gralloc4::PlaneLayoutComponentType_Y.value ||
-          comp.type.value == android::gralloc4::PlaneLayoutComponentType_CB.value ||
-          comp.type.value == android::gralloc4::PlaneLayoutComponentType_CR.value) {
-        comp.offsetInBits = 0;
-        comp.sizeInBits = 10;
-      } else {
-        return Error::BAD_VALUE;
-      }
-      break;
-    case static_cast<int32_t>(HAL_PIXEL_FORMAT_YCbCr_420_P010_VENUS):
-      if (comp.type.value == android::gralloc4::PlaneLayoutComponentType_Y.value ||
-          comp.type.value == android::gralloc4::PlaneLayoutComponentType_CB.value) {
-        comp.offsetInBits = 6;
-        comp.sizeInBits = 10;
-      } else if (comp.type.value == android::gralloc4::PlaneLayoutComponentType_CR.value) {
-        comp.offsetInBits = 22;
-        comp.sizeInBits = 10;
-      } else {
-        return Error::BAD_VALUE;
-      }
-      break;
-
-    case static_cast<int32_t>(HAL_PIXEL_FORMAT_RAW16):
-      if (comp.type.value == android::gralloc4::PlaneLayoutComponentType_RAW.value) {
-        comp.offsetInBits = 0;
-        comp.sizeInBits = 16;
-      } else {
-        return Error::BAD_VALUE;
-      }
-      break;
-    case static_cast<int32_t>(HAL_PIXEL_FORMAT_RAW12):
-    case static_cast<int32_t>(HAL_PIXEL_FORMAT_RAW10):
-      if (comp.type.value == android::gralloc4::PlaneLayoutComponentType_RAW.value) {
-        comp.offsetInBits = 0;
-        comp.sizeInBits = -1;
-      } else {
-        return Error::BAD_VALUE;
-      }
-      break;
-    case static_cast<int32_t>(HAL_PIXEL_FORMAT_RAW8):
-      if (comp.type.value == android::gralloc4::PlaneLayoutComponentType_RAW.value) {
-        comp.offsetInBits = 0;
-        comp.sizeInBits = 8;
-      } else {
-        return Error::BAD_VALUE;
-      }
-      break;
-    default:
-      ALOGI_IF(DEBUG, "Offset and size in bits unknown for format %d", format);
-      return Error::UNSUPPORTED;
-  }
-  return Error::NONE;
-}
-
-static void grallocToStandardPlaneLayoutComponentType(uint32_t in,
-                                                      std::vector<PlaneLayoutComponent> *components,
-                                                      int32_t format) {
-  PlaneLayoutComponent comp;
-  comp.offsetInBits = -1;
-  comp.sizeInBits = -1;
-
-  if (in & PLANE_COMPONENT_Y) {
-    comp.type = android::gralloc4::PlaneLayoutComponentType_Y;
-    if (getComponentSizeAndOffset(format, comp) == Error::NONE)
-      components->push_back(comp);
-  }
-
-  if (in & PLANE_COMPONENT_Cb) {
-    comp.type = android::gralloc4::PlaneLayoutComponentType_CB;
-    if (getComponentSizeAndOffset(format, comp) == Error::NONE)
-      components->push_back(comp);
-  }
-
-  if (in & PLANE_COMPONENT_Cr) {
-    comp.type = android::gralloc4::PlaneLayoutComponentType_CR;
-    if (getComponentSizeAndOffset(format, comp) == Error::NONE)
-      components->push_back(comp);
-  }
-
-  if (in & PLANE_COMPONENT_R) {
-    comp.type = android::gralloc4::PlaneLayoutComponentType_R;
-    if (getComponentSizeAndOffset(format, comp) == Error::NONE)
-      components->push_back(comp);
-  }
-
-  if (in & PLANE_COMPONENT_G) {
-    comp.type = android::gralloc4::PlaneLayoutComponentType_G;
-    if (getComponentSizeAndOffset(format, comp) == Error::NONE)
-      components->push_back(comp);
-  }
-
-  if (in & PLANE_COMPONENT_B) {
-    comp.type = android::gralloc4::PlaneLayoutComponentType_B;
-    if (getComponentSizeAndOffset(format, comp) == Error::NONE)
-      components->push_back(comp);
-  }
-
-  if (in & PLANE_COMPONENT_A) {
-    comp.type = android::gralloc4::PlaneLayoutComponentType_A;
-    if (getComponentSizeAndOffset(format, comp) == Error::NONE)
-      components->push_back(comp);
-  }
-
-  if (in & PLANE_COMPONENT_RAW) {
-    comp.type = android::gralloc4::PlaneLayoutComponentType_RAW;
-    if (getComponentSizeAndOffset(format, comp) == Error::NONE)
-      components->push_back(comp);
-  }
-
-  if (in & PLANE_COMPONENT_META) {
-    comp.type = qtigralloc::PlaneLayoutComponentType_Meta;
-    components->push_back(comp);
-  }
-}
-
-static Error getFormatLayout(private_handle_t *handle, std::vector<PlaneLayout> *out) {
-  std::vector<PlaneLayout> plane_info;
-  int plane_count = 0;
-  BufferInfo info(handle->unaligned_width, handle->unaligned_height, handle->format, handle->usage);
-
-  gralloc::PlaneLayoutInfo plane_layout[8] = {};
-  if (gralloc::IsYuvFormat(handle->format)) {
-    gralloc::GetYUVPlaneInfo(info, handle->format, handle->width, handle->height, handle->flags,
-                             &plane_count, plane_layout);
-  } else if (gralloc::IsUncompressedRGBFormat(handle->format) ||
-             gralloc::IsCompressedRGBFormat(handle->format)) {
-    gralloc::GetRGBPlaneInfo(info, handle->format, handle->width, handle->height, handle->flags,
-                             &plane_count, plane_layout);
-  } else {
-    return Error::BAD_BUFFER;
-  }
-  plane_info.resize(plane_count);
-  for (int i = 0; i < plane_count; i++) {
-    std::vector<PlaneLayoutComponent> components;
-    grallocToStandardPlaneLayoutComponentType(plane_layout[i].component, &plane_info[i].components,
-                                              handle->format);
-    plane_info[i].horizontalSubsampling = (1ull << plane_layout[i].h_subsampling);
-    plane_info[i].verticalSubsampling = (1ull << plane_layout[i].v_subsampling);
-    plane_info[i].offsetInBytes = static_cast<int64_t>(plane_layout[i].offset);
-    plane_info[i].sampleIncrementInBits = static_cast<int64_t>(plane_layout[i].step * 8);
-    plane_info[i].strideInBytes = static_cast<int64_t>(plane_layout[i].stride_bytes);
-    plane_info[i].totalSizeInBytes = static_cast<int64_t>(plane_layout[i].size);
-    plane_info[i].widthInSamples = handle->unaligned_width >> plane_layout[i].h_subsampling;
-    plane_info[i].heightInSamples = handle->unaligned_height >> plane_layout[i].v_subsampling;
-  }
-  *out = plane_info;
-  return Error::NONE;
-}
-
 int BufferManager::GetCustomDimensions(private_handle_t *hnd, int *stride, int *height) {
   auto metadata = reinterpret_cast<MetaData_t *>(hnd->base_metadata);
   hidl_vec<uint8_t> crop;
@@ -861,7 +287,7 @@
     return Error::BAD_BUFFER;
   }
 
-  auto meta_size = getMetaDataSize(buf->reserved_size);
+  auto meta_size = GetMetaDataSize(buf->reserved_size);
 
   if (allocator_->FreeBuffer(reinterpret_cast<void *>(hnd->base), hnd->size, hnd->offset, hnd->fd,
                              buf->ion_handle_main) != 0) {
@@ -945,7 +371,7 @@
   hnd->base_metadata = 0;
   hnd->gpuaddr = 0;
 
-  if (validateAndMap(hnd)) {
+  if (ValidateAndMap(hnd)) {
     ALOGE("Failed to map metadata: hnd: %p, fd:%d, id:%" PRIu64, hnd, hnd->fd, hnd->id);
     return Error::BAD_BUFFER;
   }
@@ -1204,7 +630,7 @@
 
   // Allocate memory for MetaData
   AllocData e_data;
-  e_data.size = static_cast<unsigned int>(getMetaDataSize(descriptor.GetReservedSize()));
+  e_data.size = static_cast<unsigned int>(GetMetaDataSize(descriptor.GetReservedSize()));
   e_data.handle = data.handle;
   e_data.align = page_size;
 
@@ -1243,13 +669,13 @@
   }
 
 #ifdef METADATA_V2
-  auto error = validateAndMap(hnd, descriptor.GetReservedSize());
+  auto error = ValidateAndMap(hnd, descriptor.GetReservedSize());
 #else
-  auto error = validateAndMap(hnd);
+  auto error = ValidateAndMap(hnd);
 #endif
 
   if (error != 0) {
-    ALOGE("validateAndMap failed");
+    ALOGE("ValidateAndMap failed");
     return Error::BAD_BUFFER;
   }
   auto metadata = reinterpret_cast<MetaData_t *>(hnd->base_metadata);
@@ -1268,7 +694,7 @@
   metadata->crop.right = hnd->width;
   metadata->crop.bottom = hnd->height;
 
-  unmapAndReset(hnd, descriptor.GetReservedSize());
+  UnmapAndReset(hnd, descriptor.GetReservedSize());
 
   *handle = hnd;
 
@@ -1377,6 +803,23 @@
   return Error::NONE;
 }
 
+Error BufferManager::GetMetadataValue(private_handle_t *handle, int64_t metadatatype_value,
+                                      void *param) {
+  std::lock_guard<std::mutex> lock(buffer_lock_);
+  if (!handle)
+    return Error::BAD_BUFFER;
+  auto buf = GetBufferFromHandleLocked(handle);
+  if (buf == nullptr)
+    return Error::BAD_BUFFER;
+
+  if (!handle->base_metadata) {
+    return Error::BAD_BUFFER;
+  }
+
+  auto metadata = reinterpret_cast<MetaData_t *>(handle->base_metadata);
+  return GetMetaDataValue(handle, metadatatype_value, param);
+}
+
 Error BufferManager::GetMetadata(private_handle_t *handle, int64_t metadatatype_value,
                                  hidl_vec<uint8_t> *out) {
   std::lock_guard<std::mutex> lock(buffer_lock_);
@@ -1392,29 +835,59 @@
 
   auto metadata = reinterpret_cast<MetaData_t *>(handle->base_metadata);
 
+  void *metadata_ptr = nullptr;
+  auto result = GetMetaDataByReference(handle, metadatatype_value, &metadata_ptr);
   Error error = Error::NONE;
   switch (metadatatype_value) {
     case (int64_t)StandardMetadataType::BUFFER_ID:
-      android::gralloc4::encodeBufferId((uint64_t)handle->id, out);
+      if (metadata_ptr != nullptr) {
+        android::gralloc4::encodeBufferId(*reinterpret_cast<uint64_t *>(metadata_ptr), out);
+      } else {
+        return Error::BAD_VALUE;
+      }
       break;
     case (int64_t)StandardMetadataType::NAME: {
-      std::string name(metadata->name);
-      android::gralloc4::encodeName(name, out);
+      if (metadata_ptr != nullptr) {
+        std::string name(reinterpret_cast<char *>(metadata_ptr));
+        android::gralloc4::encodeName(name, out);
+      } else {
+        return Error::BAD_VALUE;
+      }
       break;
     }
     case (int64_t)StandardMetadataType::WIDTH:
-      android::gralloc4::encodeWidth((uint64_t)handle->unaligned_width, out);
+      if (metadata_ptr != nullptr) {
+        android::gralloc4::encodeWidth(
+            static_cast<uint64_t>(*reinterpret_cast<int32_t *>(metadata_ptr)), out);
+      } else {
+        return Error::BAD_VALUE;
+      }
       break;
     case (int64_t)StandardMetadataType::HEIGHT:
-      android::gralloc4::encodeHeight((uint64_t)handle->unaligned_height, out);
+      if (metadata_ptr != nullptr) {
+        android::gralloc4::encodeHeight(
+            static_cast<uint64_t>(*reinterpret_cast<int32_t *>(metadata_ptr)), out);
+      } else {
+        return Error::BAD_VALUE;
+      }
       break;
     case (int64_t)StandardMetadataType::LAYER_COUNT:
-      android::gralloc4::encodeLayerCount((uint64_t)handle->layer_count, out);
+      if (metadata_ptr != nullptr) {
+        android::gralloc4::encodeLayerCount(
+            static_cast<uint64_t>(*reinterpret_cast<uint32_t *>(metadata_ptr)), out);
+      } else {
+        return Error::BAD_VALUE;
+      }
       break;
     case (int64_t)StandardMetadataType::PIXEL_FORMAT_REQUESTED:
-      // TODO(tbalacha): need to return IMPLEMENTATION_DEFINED,
+      // TODO(user): need to return IMPLEMENTATION_DEFINED,
       // which wouldn't be known from private_handle_t
-      android::gralloc4::encodePixelFormatRequested((PixelFormat)handle->format, out);
+      if (metadata_ptr != nullptr) {
+        android::gralloc4::encodePixelFormatRequested(
+            static_cast<PixelFormat>(*reinterpret_cast<int32_t *>(metadata_ptr)), out);
+      } else {
+        return Error::BAD_VALUE;
+      }
       break;
     case (int64_t)StandardMetadataType::PIXEL_FORMAT_FOURCC: {
       uint32_t drm_format = 0;
@@ -1431,12 +904,21 @@
       break;
     }
     case (int64_t)StandardMetadataType::USAGE:
-      android::gralloc4::encodeUsage((uint64_t)handle->usage, out);
+      if (metadata_ptr != nullptr) {
+        android::gralloc4::encodeUsage(*reinterpret_cast<uint64_t *>(metadata_ptr), out);
+      } else {
+        return Error::BAD_VALUE;
+      }
       break;
     case (int64_t)StandardMetadataType::ALLOCATION_SIZE:
-      android::gralloc4::encodeAllocationSize((uint64_t)handle->size, out);
+      if (metadata_ptr != nullptr) {
+        android::gralloc4::encodeAllocationSize(*reinterpret_cast<uint64_t *>(metadata_ptr), out);
+      } else {
+        return Error::BAD_VALUE;
+      }
       break;
     case (int64_t)StandardMetadataType::PROTECTED_CONTENT: {
+      // update to use metadata ptr when implemented
       uint64_t protected_content = (handle->flags & qtigralloc::PRIV_FLAGS_SECURE_BUFFER) ? 1 : 0;
       android::gralloc4::encodeProtectedContent(protected_content, out);
       break;
@@ -1449,7 +931,7 @@
       if (metadata->isStandardMetadataSet[GET_STANDARD_METADATA_STATUS_INDEX(metadatatype_value)]) {
 #endif
         Dataspace dataspace;
-        colorMetadataToDataspace(metadata->color, &dataspace);
+        ColorMetadataToDataspace(metadata->color, &dataspace);
         android::gralloc4::encodeDataspace(dataspace, out);
 #ifdef METADATA_V2
       } else {
@@ -1474,12 +956,16 @@
       break;
     case (int64_t)StandardMetadataType::PLANE_LAYOUTS: {
       std::vector<PlaneLayout> plane_layouts;
-      getFormatLayout(handle, &plane_layouts);
+      GetPlaneLayout(handle, &plane_layouts);
       android::gralloc4::encodePlaneLayouts(plane_layouts, out);
       break;
     }
     case (int64_t)StandardMetadataType::BLEND_MODE:
-      android::gralloc4::encodeBlendMode((BlendMode)metadata->blendMode, out);
+      if (metadata_ptr != nullptr) {
+        android::gralloc4::encodeBlendMode(*reinterpret_cast<BlendMode *>(metadata_ptr), out);
+      } else {
+        return Error::BAD_VALUE;
+      }
       break;
     case (int64_t)StandardMetadataType::SMPTE2086: {
       if (metadata->color.masteringDisplayInfo.colorVolumeSEIEnabled) {
@@ -1550,79 +1036,164 @@
       break;
     }
     case QTI_VT_TIMESTAMP:
-      android::gralloc4::encodeUint64(qtigralloc::MetadataType_VTTimestamp, metadata->vtTimeStamp,
-                                      out);
+      if (metadata_ptr != nullptr) {
+        android::gralloc4::encodeUint64(qtigralloc::MetadataType_VTTimestamp,
+                                        *reinterpret_cast<uint64_t *>(metadata_ptr), out);
+      } else {
+        return Error::BAD_VALUE;
+      }
       break;
     case QTI_COLOR_METADATA:
-      qtigralloc::encodeColorMetadata(metadata->color, out);
+      if (metadata_ptr != nullptr) {
+        qtigralloc::encodeColorMetadata(*reinterpret_cast<ColorMetaData *>(metadata_ptr), out);
+      } else {
+        return Error::BAD_VALUE;
+      }
       break;
     case QTI_PP_PARAM_INTERLACED:
-      android::gralloc4::encodeInt32(qtigralloc::MetadataType_PPParamInterlaced,
-                                     metadata->interlaced, out);
+      if (metadata_ptr != nullptr) {
+        android::gralloc4::encodeInt32(qtigralloc::MetadataType_PPParamInterlaced,
+                                       *reinterpret_cast<int32_t *>(metadata_ptr), out);
+      } else {
+        return Error::BAD_VALUE;
+      }
       break;
     case QTI_VIDEO_PERF_MODE:
-      android::gralloc4::encodeUint32(qtigralloc::MetadataType_VideoPerfMode,
-                                      metadata->isVideoPerfMode, out);
+      if (metadata_ptr != nullptr) {
+        android::gralloc4::encodeUint32(qtigralloc::MetadataType_VideoPerfMode,
+                                        *reinterpret_cast<uint32_t *>(metadata_ptr), out);
+      } else {
+        return Error::BAD_VALUE;
+      }
       break;
     case QTI_GRAPHICS_METADATA:
-      qtigralloc::encodeGraphicsMetadata(metadata->graphics_metadata, out);
+      if (metadata_ptr != nullptr) {
+        qtigralloc::encodeGraphicsMetadata(*reinterpret_cast<GraphicsMetadata *>(metadata_ptr),
+                                           out);
+      } else {
+        return Error::BAD_VALUE;
+      }
       break;
     case QTI_UBWC_CR_STATS_INFO:
-      qtigralloc::encodeUBWCStats(metadata->ubwcCRStats, out);
+      if (metadata_ptr != nullptr) {
+        qtigralloc::encodeUBWCStats(reinterpret_cast<UBWCStats *>(metadata_ptr), out);
+      } else {
+        return Error::BAD_VALUE;
+      }
       break;
     case QTI_REFRESH_RATE:
-      android::gralloc4::encodeFloat(qtigralloc::MetadataType_RefreshRate, metadata->refreshrate,
-                                     out);
+      if (metadata_ptr != nullptr) {
+        android::gralloc4::encodeFloat(qtigralloc::MetadataType_RefreshRate,
+                                       *reinterpret_cast<float *>(metadata_ptr), out);
+      } else {
+        return Error::BAD_VALUE;
+      }
       break;
     case QTI_MAP_SECURE_BUFFER:
-      android::gralloc4::encodeInt32(qtigralloc::MetadataType_MapSecureBuffer,
-                                     metadata->mapSecureBuffer, out);
+      if (metadata_ptr != nullptr) {
+        android::gralloc4::encodeInt32(qtigralloc::MetadataType_MapSecureBuffer,
+                                       *reinterpret_cast<int32_t *>(metadata_ptr), out);
+      } else {
+        return Error::BAD_VALUE;
+      }
       break;
     case QTI_LINEAR_FORMAT:
-      android::gralloc4::encodeUint32(qtigralloc::MetadataType_LinearFormat, metadata->linearFormat,
-                                      out);
+      if (metadata_ptr != nullptr) {
+        android::gralloc4::encodeUint32(qtigralloc::MetadataType_LinearFormat,
+                                        *reinterpret_cast<uint32_t *>(metadata_ptr), out);
+      } else {
+        return Error::BAD_VALUE;
+      }
       break;
     case QTI_SINGLE_BUFFER_MODE:
-      android::gralloc4::encodeUint32(qtigralloc::MetadataType_SingleBufferMode,
-                                      metadata->isSingleBufferMode, out);
+      if (metadata_ptr != nullptr) {
+        android::gralloc4::encodeUint32(qtigralloc::MetadataType_SingleBufferMode,
+                                        *reinterpret_cast<uint32_t *>(metadata_ptr), out);
+      } else {
+        return Error::BAD_VALUE;
+      }
       break;
     case QTI_CVP_METADATA:
-      qtigralloc::encodeCVPMetadata(metadata->cvpMetadata, out);
+      if (metadata_ptr != nullptr) {
+        qtigralloc::encodeCVPMetadata(*reinterpret_cast<CVPMetadata *>(metadata_ptr), out);
+      } else {
+        return Error::BAD_VALUE;
+      }
       break;
     case QTI_VIDEO_HISTOGRAM_STATS:
-      qtigralloc::encodeVideoHistogramMetadata(metadata->video_histogram_stats, out);
+      if (metadata_ptr != nullptr) {
+        qtigralloc::encodeVideoHistogramMetadata(
+            *reinterpret_cast<VideoHistogramMetadata *>(metadata_ptr), out);
+      } else {
+        return Error::BAD_VALUE;
+      }
       break;
     case QTI_FD:
-      android::gralloc4::encodeInt32(qtigralloc::MetadataType_FD, handle->fd, out);
+      if (metadata_ptr != nullptr) {
+        android::gralloc4::encodeInt32(qtigralloc::MetadataType_FD,
+                                       *reinterpret_cast<int32_t *>(metadata_ptr), out);
+      } else {
+        return Error::BAD_VALUE;
+      }
       break;
     case QTI_PRIVATE_FLAGS:
-      android::gralloc4::encodeInt32(qtigralloc::MetadataType_PrivateFlags, handle->flags, out);
+      if (metadata_ptr != nullptr) {
+        android::gralloc4::encodeInt32(qtigralloc::MetadataType_PrivateFlags,
+                                       *reinterpret_cast<int32_t *>(metadata_ptr), out);
+      } else {
+        return Error::BAD_VALUE;
+      }
       break;
     case QTI_ALIGNED_WIDTH_IN_PIXELS:
-      android::gralloc4::encodeUint32(qtigralloc::MetadataType_AlignedWidthInPixels, handle->width,
-                                      out);
+      if (metadata_ptr != nullptr) {
+        android::gralloc4::encodeUint32(qtigralloc::MetadataType_AlignedWidthInPixels,
+                                        *reinterpret_cast<uint32_t *>(metadata_ptr), out);
+      } else {
+        return Error::BAD_VALUE;
+      }
       break;
     case QTI_ALIGNED_HEIGHT_IN_PIXELS:
-      android::gralloc4::encodeUint32(qtigralloc::MetadataType_AlignedHeightInPixels,
-                                      handle->height, out);
+      if (metadata_ptr != nullptr) {
+        android::gralloc4::encodeUint32(qtigralloc::MetadataType_AlignedHeightInPixels,
+                                        *reinterpret_cast<uint32_t *>(metadata_ptr), out);
+      } else {
+        return Error::BAD_VALUE;
+      }
       break;
 #ifdef METADATA_V2
     case QTI_STANDARD_METADATA_STATUS:
-      qtigralloc::encodeMetadataState(metadata->isStandardMetadataSet, out);
+      if (metadata_ptr != nullptr) {
+        qtigralloc::encodeMetadataState(reinterpret_cast<bool *>(metadata_ptr), out);
+      } else {
+        return Error::BAD_VALUE;
+      }
       break;
     case QTI_VENDOR_METADATA_STATUS:
-      qtigralloc::encodeMetadataState(metadata->isVendorMetadataSet, out);
+      if (metadata_ptr != nullptr) {
+        qtigralloc::encodeMetadataState(reinterpret_cast<bool *>(metadata_ptr), out);
+      } else {
+        return Error::BAD_VALUE;
+      }
       break;
 #endif
 #ifdef QTI_BUFFER_TYPE
     case QTI_BUFFER_TYPE:
-      android::gralloc4::encodeUint32(qtigralloc::MetadataType_BufferType, handle->buffer_type,
-                                      out);
+      if (metadata_ptr != nullptr) {
+        android::gralloc4::encodeUint32(qtigralloc::MetadataType_BufferType,
+                                        *reinterpret_cast<uint32_t *>(metadata_ptr), out);
+      } else {
+        return Error::BAD_VALUE;
+      }
       break;
 #endif
 #ifdef QTI_VIDEO_TS_INFO
     case QTI_VIDEO_TS_INFO:
-      qtigralloc::encodeVideoTimestampInfo(metadata->videoTsInfo, out);
+      if (metadata_ptr != nullptr) {
+        qtigralloc::encodeVideoTimestampInfo(*reinterpret_cast<VideoTimestampInfo *>(metadata_ptr),
+                                             out);
+      } else {
+        return Error::BAD_VALUE;
+      }
       break;
 #endif
 #ifdef QTI_CUSTOM_DIMENSIONS_STRIDE
@@ -1669,7 +1240,7 @@
 #ifdef QTI_COLORSPACE
     case QTI_COLORSPACE: {
       uint32_t colorspace;
-      error = getColorSpaceFromMetaData(metadata->color, &colorspace);
+      error = GetColorSpaceFromColorMetaData(metadata->color, &colorspace);
       if (error == Error::NONE) {
         android::gralloc4::encodeUint32(qtigralloc::MetadataType_ColorSpace, colorspace, out);
         break;
diff --git a/gralloc/gr_buf_mgr.h b/gralloc/gr_buf_mgr.h
index 7d0cbbe..8334ae2 100644
--- a/gralloc/gr_buf_mgr.h
+++ b/gralloc/gr_buf_mgr.h
@@ -59,6 +59,7 @@
   Error RereadBuffer(const private_handle_t *handle);
   Error GetAllHandles(std::vector<const private_handle_t *> *out_handle_list);
   int GetCustomDimensions(private_handle_t *handle, int *stride, int *height);
+  Error GetMetadataValue(private_handle_t *handle, int64_t metadatatype_value, void *out);
 
  private:
   BufferManager();
diff --git a/gralloc/gr_utils.cpp b/gralloc/gr_utils.cpp
index de0df9c..738440e 100644
--- a/gralloc/gr_utils.cpp
+++ b/gralloc/gr_utils.cpp
@@ -29,19 +29,20 @@
 
 #ifndef QMAA
 #include <display/media/mmm_color_fmt.h>
-#endif
-
-#ifndef QMAA
 #include <display/drm/sde_drm.h>
 #include <drm/drm_fourcc.h>
 #endif
 
+#include <sys/mman.h>
 #include <cutils/properties.h>
 #include <algorithm>
+#include <string>
+#include <vector>
 
 #include "gr_adreno_info.h"
 #include "gr_camera_info.h"
 #include "gr_utils.h"
+#include "QtiGralloc.h"
 
 #define ASTC_BLOCK_SIZE 16
 
@@ -55,6 +56,12 @@
                                 BufferUsage::CAMERA_INPUT | BufferUsage::VIDEO_DECODER | \
                                 GRALLOC_USAGE_PRIVATE_CDSP | GRALLOC_USAGE_PRIVATE_SECURE_DISPLAY)
 
+using aidl::android::hardware::graphics::common::Dataspace;
+using aidl::android::hardware::graphics::common::PlaneLayout;
+using aidl::android::hardware::graphics::common::PlaneLayoutComponent;
+using aidl::android::hardware::graphics::common::StandardMetadataType;
+using ::android::hardware::graphics::common::V1_2::PixelFormat;
+
 namespace gralloc {
 
 #ifndef QMAA
@@ -1142,6 +1149,29 @@
   return 0;
 }
 
+// TODO(user): Collapse into GetColorSpaceFromMetadata with qdmetadata deprecation
+Error GetColorSpaceFromColorMetaData(ColorMetaData color_metadata, uint32_t *color_space) {
+  Error err = Error::NONE;
+  switch (color_metadata.colorPrimaries) {
+    case ColorPrimaries_BT709_5:
+      *color_space = HAL_CSC_ITU_R_709;
+      break;
+    case ColorPrimaries_BT601_6_525:
+    case ColorPrimaries_BT601_6_625:
+      *color_space = ((color_metadata.range) ? HAL_CSC_ITU_R_601_FR : HAL_CSC_ITU_R_601);
+      break;
+    case ColorPrimaries_BT2020:
+      *color_space = (color_metadata.range) ? HAL_CSC_ITU_R_2020_FR : HAL_CSC_ITU_R_2020;
+      break;
+    default:
+      err = Error::UNSUPPORTED;
+      *color_space = 0;
+      ALOGW("Unknown Color primary = %d", color_metadata.colorPrimaries);
+      break;
+  }
+  return err;
+}
+
 void GetColorSpaceFromMetadata(private_handle_t *hnd, int *color_space) {
   ColorMetaData color_metadata;
   if (getMetaData(hnd, GET_COLOR_METADATA, &color_metadata) == 0) {
@@ -2042,7 +2072,7 @@
   plane_info->scanlines = height;
 }
 
-// TODO(tbalacha): tile vs ubwc -- may need to find a diff way to differentiate
+// TODO(user): tile vs ubwc -- may need to find a diff way to differentiate
 void GetDRMFormat(uint32_t format, uint32_t flags, uint32_t *drm_format,
                   uint64_t *drm_format_modifier) {
 #ifndef QMAA
@@ -2188,4 +2218,1080 @@
 
   return can_allocate;
 }
+
+uint64_t GetMetaDataSize(uint64_t reserved_region_size) {
+// Only include the reserved region size when using Metadata_t V2
+#ifndef METADATA_V2
+  reserved_region_size = 0;
+#endif
+  return static_cast<uint64_t>(ROUND_UP_PAGESIZE(sizeof(MetaData_t) + reserved_region_size));
+}
+
+void UnmapAndReset(private_handle_t *handle, uint64_t reserved_region_size) {
+  if (private_handle_t::validate(handle) == 0 && handle->base_metadata) {
+    munmap(reinterpret_cast<void *>(handle->base_metadata), GetMetaDataSize(reserved_region_size));
+    handle->base_metadata = 0;
+  }
+}
+
+int ValidateAndMap(private_handle_t *handle, uint64_t reserved_region_size) {
+  if (private_handle_t::validate(handle)) {
+    ALOGE("%s: Private handle is invalid - handle:%p", __func__, handle);
+    return -1;
+  }
+  if (handle->fd_metadata < 0) {
+    // Silently return, metadata cannot be used
+    return -1;
+  }
+
+  if (!handle->base_metadata) {
+    uint64_t size = GetMetaDataSize(reserved_region_size);
+    void *base = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, handle->fd_metadata, 0);
+    if (base == reinterpret_cast<void *>(MAP_FAILED)) {
+      ALOGE("%s: metadata mmap failed - handle:%p fd: %d err: %s", __func__, handle,
+            handle->fd_metadata, strerror(errno));
+      return -1;
+    }
+    handle->base_metadata = (uintptr_t)base;
+#ifdef METADATA_V2
+    // The allocator process gets the reserved region size from the BufferDescriptor.
+    // When importing to another process, the reserved size is unknown until mapping the metadata,
+    // hence the re-mapping below
+    auto metadata = reinterpret_cast<MetaData_t *>(handle->base_metadata);
+    if (reserved_region_size == 0 && metadata->reservedSize) {
+      size = GetMetaDataSize(metadata->reservedSize);
+      UnmapAndReset(handle);
+      void *new_base = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, handle->fd_metadata, 0);
+      if (new_base == reinterpret_cast<void *>(MAP_FAILED)) {
+        ALOGE("%s: metadata mmap failed - handle:%p fd: %d err: %s", __func__, handle,
+              handle->fd_metadata, strerror(errno));
+        return -1;
+      }
+      handle->base_metadata = (uintptr_t)new_base;
+    }
+#endif
+  }
+  return 0;
+}
+
+int colorMetaDataToColorSpace(ColorMetaData in, ColorSpace_t *out) {
+  if (in.colorPrimaries == ColorPrimaries_BT601_6_525 ||
+      in.colorPrimaries == ColorPrimaries_BT601_6_625) {
+    if (in.range == Range_Full) {
+      *out = ITU_R_601_FR;
+    } else {
+      *out = ITU_R_601;
+    }
+  } else if (in.colorPrimaries == ColorPrimaries_BT2020) {
+    if (in.range == Range_Full) {
+      *out = ITU_R_2020_FR;
+    } else {
+      *out = ITU_R_2020;
+    }
+  } else if (in.colorPrimaries == ColorPrimaries_BT709_5) {
+    if (in.range == Range_Full) {
+      *out = ITU_R_709_FR;
+    } else {
+      *out = ITU_R_709;
+    }
+  } else {
+    ALOGE(
+        "Cannot convert ColorMetaData to ColorSpace_t. "
+        "Primaries = %d, Range = %d",
+        in.colorPrimaries, in.range);
+    return -1;
+  }
+
+  return 0;
+}
+
+bool getGralloc4Array(MetaData_t *metadata, int32_t paramType) {
+  switch (paramType) {
+    case QTI_VT_TIMESTAMP:
+      return metadata->isVendorMetadataSet[GET_VENDOR_METADATA_STATUS_INDEX(QTI_VT_TIMESTAMP)];
+    case QTI_COLOR_METADATA:
+      return metadata->isVendorMetadataSet[GET_VENDOR_METADATA_STATUS_INDEX(QTI_COLOR_METADATA)];
+    case QTI_PP_PARAM_INTERLACED:
+      return metadata
+          ->isVendorMetadataSet[GET_VENDOR_METADATA_STATUS_INDEX(QTI_PP_PARAM_INTERLACED)];
+    case QTI_VIDEO_PERF_MODE:
+      return metadata->isVendorMetadataSet[GET_VENDOR_METADATA_STATUS_INDEX(QTI_VIDEO_PERF_MODE)];
+    case QTI_GRAPHICS_METADATA:
+      return metadata->isVendorMetadataSet[GET_VENDOR_METADATA_STATUS_INDEX(QTI_GRAPHICS_METADATA)];
+    case QTI_UBWC_CR_STATS_INFO:
+      return metadata
+          ->isVendorMetadataSet[GET_VENDOR_METADATA_STATUS_INDEX(QTI_UBWC_CR_STATS_INFO)];
+    case (int64_t)StandardMetadataType::CROP:
+      return metadata->isStandardMetadataSet[GET_STANDARD_METADATA_STATUS_INDEX(
+          ::android::gralloc4::MetadataType_Crop.value)];
+    case QTI_REFRESH_RATE:
+      return metadata->isVendorMetadataSet[GET_VENDOR_METADATA_STATUS_INDEX(QTI_REFRESH_RATE)];
+    case QTI_COLORSPACE:
+      return metadata->isVendorMetadataSet[GET_VENDOR_METADATA_STATUS_INDEX(QTI_COLOR_METADATA)];
+    case QTI_MAP_SECURE_BUFFER:
+      return metadata->isVendorMetadataSet[GET_VENDOR_METADATA_STATUS_INDEX(QTI_MAP_SECURE_BUFFER)];
+    case QTI_LINEAR_FORMAT:
+      return metadata->isVendorMetadataSet[GET_VENDOR_METADATA_STATUS_INDEX(QTI_LINEAR_FORMAT)];
+    case QTI_SINGLE_BUFFER_MODE:
+      return metadata
+          ->isVendorMetadataSet[GET_VENDOR_METADATA_STATUS_INDEX(QTI_SINGLE_BUFFER_MODE)];
+    case QTI_CVP_METADATA:
+      return metadata->isVendorMetadataSet[GET_VENDOR_METADATA_STATUS_INDEX(QTI_CVP_METADATA)];
+    case QTI_VIDEO_HISTOGRAM_STATS:
+      return metadata
+          ->isVendorMetadataSet[GET_VENDOR_METADATA_STATUS_INDEX(QTI_VIDEO_HISTOGRAM_STATS)];
+    case QTI_VIDEO_TS_INFO:
+      return metadata
+          ->isVendorMetadataSet[GET_VENDOR_METADATA_STATUS_INDEX(QTI_VIDEO_TS_INFO)];
+    case QTI_S3D_FORMAT:
+      return metadata->isVendorMetadataSet[GET_VENDOR_METADATA_STATUS_INDEX(QTI_S3D_FORMAT)];
+    case (int64_t)StandardMetadataType::BLEND_MODE:
+      return metadata->isStandardMetadataSet[GET_STANDARD_METADATA_STATUS_INDEX(
+          ::android::gralloc4::MetadataType_BlendMode.value)];
+    // Following metadata types are not changed after allocation - treat as set by default
+    case (int64_t)StandardMetadataType::BUFFER_ID:
+    case (int64_t)StandardMetadataType::NAME:
+    case (int64_t)StandardMetadataType::WIDTH:
+    case (int64_t)StandardMetadataType::HEIGHT:
+    case (int64_t)StandardMetadataType::LAYER_COUNT:
+    case (int64_t)StandardMetadataType::PIXEL_FORMAT_REQUESTED:
+    case (int64_t)StandardMetadataType::USAGE:
+    case (int64_t)StandardMetadataType::PIXEL_FORMAT_FOURCC:
+    case (int64_t)StandardMetadataType::PIXEL_FORMAT_MODIFIER:
+    case (int64_t)StandardMetadataType::PROTECTED_CONTENT:
+    case (int64_t)StandardMetadataType::ALLOCATION_SIZE:
+    case QTI_FD:
+    case QTI_PRIVATE_FLAGS:
+    case QTI_ALIGNED_WIDTH_IN_PIXELS:
+    case QTI_ALIGNED_HEIGHT_IN_PIXELS:
+    case QTI_STANDARD_METADATA_STATUS:
+    case QTI_VENDOR_METADATA_STATUS:
+    case QTI_RGB_DATA_ADDRESS:
+    case QTI_YUV_PLANE_INFO:
+    case QTI_CUSTOM_DIMENSIONS_STRIDE:
+    case QTI_CUSTOM_DIMENSIONS_HEIGHT:
+    case QTI_BUFFER_TYPE:
+    case (int64_t)StandardMetadataType::DATASPACE:
+    case (int64_t)StandardMetadataType::PLANE_LAYOUTS:
+      return true;
+    default:
+      ALOGE("paramType %d not supported", paramType);
+      return false;
+  }
+}
+
+Error GetMetaDataByReference(void *buffer, int64_t type, void **out) {
+  return GetMetaDataInternal(buffer, type, nullptr, out);
+}
+
+Error GetMetaDataValue(void *buffer, int64_t type, void *in) {
+  return GetMetaDataInternal(buffer, type, in, nullptr);
+}
+
+Error ColorMetadataToDataspace(ColorMetaData color_metadata, Dataspace *dataspace) {
+  Dataspace primaries, transfer, range = Dataspace::UNKNOWN;
+
+  switch (color_metadata.colorPrimaries) {
+    case ColorPrimaries_BT709_5:
+      primaries = Dataspace::STANDARD_BT709;
+      break;
+    // TODO(user): verify this is equivalent
+    case ColorPrimaries_BT470_6M:
+      primaries = Dataspace::STANDARD_BT470M;
+      break;
+    case ColorPrimaries_BT601_6_625:
+      primaries = Dataspace::STANDARD_BT601_625;
+      break;
+    case ColorPrimaries_BT601_6_525:
+      primaries = Dataspace::STANDARD_BT601_525;
+      break;
+    case ColorPrimaries_GenericFilm:
+      primaries = Dataspace::STANDARD_FILM;
+      break;
+    case ColorPrimaries_BT2020:
+      primaries = Dataspace::STANDARD_BT2020;
+      break;
+    case ColorPrimaries_AdobeRGB:
+      primaries = Dataspace::STANDARD_ADOBE_RGB;
+      break;
+    case ColorPrimaries_DCIP3:
+      primaries = Dataspace::STANDARD_DCI_P3;
+      break;
+    default:
+      return Error::UNSUPPORTED;
+      /*
+       ColorPrimaries_SMPTE_240M;
+       ColorPrimaries_SMPTE_ST428;
+       ColorPrimaries_EBU3213;
+      */
+  }
+
+  switch (color_metadata.transfer) {
+    case Transfer_sRGB:
+      transfer = Dataspace::TRANSFER_SRGB;
+      break;
+    case Transfer_Gamma2_2:
+      transfer = Dataspace::TRANSFER_GAMMA2_2;
+      break;
+    case Transfer_Gamma2_8:
+      transfer = Dataspace::TRANSFER_GAMMA2_8;
+      break;
+    case Transfer_SMPTE_170M:
+      transfer = Dataspace::TRANSFER_SMPTE_170M;
+      break;
+    case Transfer_Linear:
+      transfer = Dataspace::TRANSFER_LINEAR;
+      break;
+    case Transfer_HLG:
+      transfer = Dataspace::TRANSFER_HLG;
+      break;
+    default:
+      return Error::UNSUPPORTED;
+      /*
+      Transfer_SMPTE_240M
+      Transfer_Log
+      Transfer_Log_Sqrt
+      Transfer_XvYCC
+      Transfer_BT1361
+      Transfer_sYCC
+      Transfer_BT2020_2_1
+      Transfer_BT2020_2_2
+      Transfer_SMPTE_ST2084
+      Transfer_ST_428
+      */
+  }
+
+  switch (color_metadata.range) {
+    case Range_Full:
+      range = Dataspace::RANGE_FULL;
+      break;
+    case Range_Limited:
+      range = Dataspace::RANGE_LIMITED;
+      break;
+    case Range_Extended:
+      range = Dataspace::RANGE_EXTENDED;
+      break;
+    default:
+      return Error::UNSUPPORTED;
+  }
+
+  *dataspace = (Dataspace)((uint32_t)primaries | (uint32_t)transfer | (uint32_t)range);
+  return Error::NONE;
+}
+
+static Error getComponentSizeAndOffset(int32_t format, PlaneLayoutComponent &comp) {
+  switch (format) {
+    case static_cast<int32_t>(HAL_PIXEL_FORMAT_RGBA_8888):
+    case static_cast<int32_t>(HAL_PIXEL_FORMAT_RGBX_8888):
+    case static_cast<int32_t>(HAL_PIXEL_FORMAT_RGB_888):
+      comp.sizeInBits = 8;
+      if (comp.type.value == android::gralloc4::PlaneLayoutComponentType_R.value) {
+        comp.offsetInBits = 0;
+      } else if (comp.type.value == android::gralloc4::PlaneLayoutComponentType_G.value) {
+        comp.offsetInBits = 8;
+      } else if (comp.type.value == android::gralloc4::PlaneLayoutComponentType_B.value) {
+        comp.offsetInBits = 16;
+      } else if (comp.type.value == android::gralloc4::PlaneLayoutComponentType_A.value &&
+                 format != HAL_PIXEL_FORMAT_RGB_888) {
+        comp.offsetInBits = 24;
+      } else {
+        return Error::BAD_VALUE;
+      }
+      break;
+    case static_cast<int32_t>(HAL_PIXEL_FORMAT_RGB_565):
+      if (comp.type.value == android::gralloc4::PlaneLayoutComponentType_R.value) {
+        comp.offsetInBits = 0;
+        comp.sizeInBits = 5;
+      } else if (comp.type.value == android::gralloc4::PlaneLayoutComponentType_G.value) {
+        comp.offsetInBits = 5;
+        comp.sizeInBits = 6;
+      } else if (comp.type.value == android::gralloc4::PlaneLayoutComponentType_B.value) {
+        comp.offsetInBits = 11;
+        comp.sizeInBits = 5;
+      } else {
+        return Error::BAD_VALUE;
+      }
+      break;
+    case static_cast<int32_t>(HAL_PIXEL_FORMAT_BGR_565):
+      if (comp.type.value == android::gralloc4::PlaneLayoutComponentType_R.value) {
+        comp.offsetInBits = 11;
+        comp.sizeInBits = 5;
+      } else if (comp.type.value == android::gralloc4::PlaneLayoutComponentType_G.value) {
+        comp.offsetInBits = 5;
+        comp.sizeInBits = 6;
+      } else if (comp.type.value == android::gralloc4::PlaneLayoutComponentType_B.value) {
+        comp.offsetInBits = 0;
+        comp.sizeInBits = 5;
+      } else {
+        return Error::BAD_VALUE;
+      }
+      break;
+    case static_cast<int32_t>(HAL_PIXEL_FORMAT_BGRA_8888):
+    case static_cast<int32_t>(HAL_PIXEL_FORMAT_BGRX_8888):
+    case static_cast<int32_t>(HAL_PIXEL_FORMAT_BGR_888):
+      comp.sizeInBits = 8;
+      if (comp.type.value == android::gralloc4::PlaneLayoutComponentType_R.value) {
+        comp.offsetInBits = 16;
+      } else if (comp.type.value == android::gralloc4::PlaneLayoutComponentType_G.value) {
+        comp.offsetInBits = 8;
+      } else if (comp.type.value == android::gralloc4::PlaneLayoutComponentType_B.value) {
+        comp.offsetInBits = 0;
+      } else if (comp.type.value == android::gralloc4::PlaneLayoutComponentType_A.value &&
+                 format != HAL_PIXEL_FORMAT_BGR_888) {
+        comp.offsetInBits = 24;
+      } else {
+        return Error::BAD_VALUE;
+      }
+      break;
+    case static_cast<int32_t>(HAL_PIXEL_FORMAT_RGBA_5551):
+      if (comp.type.value == android::gralloc4::PlaneLayoutComponentType_R.value) {
+        comp.sizeInBits = 5;
+        comp.offsetInBits = 0;
+      } else if (comp.type.value == android::gralloc4::PlaneLayoutComponentType_G.value) {
+        comp.sizeInBits = 5;
+        comp.offsetInBits = 5;
+      } else if (comp.type.value == android::gralloc4::PlaneLayoutComponentType_B.value) {
+        comp.sizeInBits = 5;
+        comp.offsetInBits = 10;
+      } else if (comp.type.value == android::gralloc4::PlaneLayoutComponentType_A.value) {
+        comp.sizeInBits = 1;
+        comp.offsetInBits = 15;
+      } else {
+        return Error::BAD_VALUE;
+      }
+      break;
+    case static_cast<int32_t>(HAL_PIXEL_FORMAT_RGBA_4444):
+      if (comp.type.value == android::gralloc4::PlaneLayoutComponentType_R.value) {
+        comp.sizeInBits = 4;
+        comp.offsetInBits = 0;
+      } else if (comp.type.value == android::gralloc4::PlaneLayoutComponentType_G.value) {
+        comp.sizeInBits = 4;
+        comp.offsetInBits = 4;
+      } else if (comp.type.value == android::gralloc4::PlaneLayoutComponentType_B.value) {
+        comp.sizeInBits = 4;
+        comp.offsetInBits = 8;
+      } else if (comp.type.value == android::gralloc4::PlaneLayoutComponentType_A.value) {
+        comp.sizeInBits = 4;
+        comp.offsetInBits = 12;
+      } else {
+        return Error::BAD_VALUE;
+      }
+      break;
+    case static_cast<int32_t>(HAL_PIXEL_FORMAT_R_8):
+    case static_cast<int32_t>(HAL_PIXEL_FORMAT_RG_88):
+      comp.sizeInBits = 8;
+      if (comp.type.value == android::gralloc4::PlaneLayoutComponentType_R.value) {
+        comp.offsetInBits = 0;
+      } else if (comp.type.value == android::gralloc4::PlaneLayoutComponentType_G.value &&
+                 format != HAL_PIXEL_FORMAT_R_8) {
+        comp.offsetInBits = 8;
+      } else {
+        return Error::BAD_VALUE;
+      }
+      break;
+    case static_cast<int32_t>(HAL_PIXEL_FORMAT_RGBA_1010102):
+    case static_cast<int32_t>(HAL_PIXEL_FORMAT_RGBX_1010102):
+      if (comp.type.value == android::gralloc4::PlaneLayoutComponentType_R.value) {
+        comp.sizeInBits = 10;
+        comp.offsetInBits = 0;
+      } else if (comp.type.value == android::gralloc4::PlaneLayoutComponentType_G.value) {
+        comp.sizeInBits = 10;
+        comp.offsetInBits = 10;
+      } else if (comp.type.value == android::gralloc4::PlaneLayoutComponentType_B.value) {
+        comp.sizeInBits = 10;
+        comp.offsetInBits = 20;
+      } else if (comp.type.value == android::gralloc4::PlaneLayoutComponentType_A.value) {
+        comp.sizeInBits = 2;
+        comp.offsetInBits = 30;
+      } else {
+        return Error::BAD_VALUE;
+      }
+      break;
+    case static_cast<int32_t>(HAL_PIXEL_FORMAT_ARGB_2101010):
+    case static_cast<int32_t>(HAL_PIXEL_FORMAT_XRGB_2101010):
+      if (comp.type.value == android::gralloc4::PlaneLayoutComponentType_R.value) {
+        comp.sizeInBits = 10;
+        comp.offsetInBits = 2;
+      } else if (comp.type.value == android::gralloc4::PlaneLayoutComponentType_G.value) {
+        comp.sizeInBits = 10;
+        comp.offsetInBits = 12;
+      } else if (comp.type.value == android::gralloc4::PlaneLayoutComponentType_B.value) {
+        comp.sizeInBits = 10;
+        comp.offsetInBits = 22;
+      } else if (comp.type.value == android::gralloc4::PlaneLayoutComponentType_A.value) {
+        comp.sizeInBits = 2;
+        comp.offsetInBits = 0;
+      } else {
+        return Error::BAD_VALUE;
+      }
+      break;
+    case static_cast<int32_t>(HAL_PIXEL_FORMAT_BGRA_1010102):
+    case static_cast<int32_t>(HAL_PIXEL_FORMAT_BGRX_1010102):
+      if (comp.type.value == android::gralloc4::PlaneLayoutComponentType_R.value) {
+        comp.sizeInBits = 10;
+        comp.offsetInBits = 20;
+      } else if (comp.type.value == android::gralloc4::PlaneLayoutComponentType_G.value) {
+        comp.sizeInBits = 10;
+        comp.offsetInBits = 10;
+      } else if (comp.type.value == android::gralloc4::PlaneLayoutComponentType_B.value) {
+        comp.sizeInBits = 10;
+        comp.offsetInBits = 0;
+      } else if (comp.type.value == android::gralloc4::PlaneLayoutComponentType_A.value) {
+        comp.sizeInBits = 2;
+        comp.offsetInBits = 30;
+      } else {
+        return Error::BAD_VALUE;
+      }
+      break;
+    case static_cast<int32_t>(HAL_PIXEL_FORMAT_ABGR_2101010):
+    case static_cast<int32_t>(HAL_PIXEL_FORMAT_XBGR_2101010):
+      if (comp.type.value == android::gralloc4::PlaneLayoutComponentType_R.value) {
+        comp.sizeInBits = 10;
+        comp.offsetInBits = 22;
+      } else if (comp.type.value == android::gralloc4::PlaneLayoutComponentType_G.value) {
+        comp.sizeInBits = 10;
+        comp.offsetInBits = 12;
+      } else if (comp.type.value == android::gralloc4::PlaneLayoutComponentType_B.value) {
+        comp.sizeInBits = 10;
+        comp.offsetInBits = 2;
+      } else if (comp.type.value == android::gralloc4::PlaneLayoutComponentType_A.value) {
+        comp.sizeInBits = 2;
+        comp.offsetInBits = 0;
+      } else {
+        return Error::BAD_VALUE;
+      }
+      break;
+    case static_cast<int32_t>(HAL_PIXEL_FORMAT_RGBA_FP16):
+      if (comp.type.value == android::gralloc4::PlaneLayoutComponentType_R.value) {
+        comp.sizeInBits = 16;
+        comp.offsetInBits = 0;
+      } else if (comp.type.value == android::gralloc4::PlaneLayoutComponentType_G.value) {
+        comp.sizeInBits = 16;
+        comp.offsetInBits = 16;
+      } else if (comp.type.value == android::gralloc4::PlaneLayoutComponentType_B.value) {
+        comp.sizeInBits = 16;
+        comp.offsetInBits = 32;
+      } else if (comp.type.value == android::gralloc4::PlaneLayoutComponentType_A.value) {
+        comp.sizeInBits = 16;
+        comp.offsetInBits = 48;
+      } else {
+        return Error::BAD_VALUE;
+      }
+      break;
+    case static_cast<int32_t>(HAL_PIXEL_FORMAT_YCbCr_420_SP):
+    case static_cast<int32_t>(HAL_PIXEL_FORMAT_YCbCr_422_SP):
+    case static_cast<int32_t>(HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS):
+    case static_cast<int32_t>(HAL_PIXEL_FORMAT_NV12_ENCODEABLE):
+      comp.sizeInBits = 8;
+      if (comp.type.value == android::gralloc4::PlaneLayoutComponentType_Y.value ||
+          comp.type.value == android::gralloc4::PlaneLayoutComponentType_CB.value) {
+        comp.offsetInBits = 0;
+      } else if (comp.type.value == android::gralloc4::PlaneLayoutComponentType_CR.value) {
+        comp.offsetInBits = 8;
+      } else {
+        return Error::BAD_VALUE;
+      }
+      break;
+    case static_cast<int32_t>(HAL_PIXEL_FORMAT_YCrCb_420_SP):
+    case static_cast<int32_t>(HAL_PIXEL_FORMAT_YCrCb_422_SP):
+    case static_cast<int32_t>(HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO):
+    case static_cast<int32_t>(HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS):
+    case static_cast<int32_t>(HAL_PIXEL_FORMAT_NV21_ZSL):
+      comp.sizeInBits = 8;
+      if (comp.type.value == android::gralloc4::PlaneLayoutComponentType_Y.value ||
+          comp.type.value == android::gralloc4::PlaneLayoutComponentType_CR.value) {
+        comp.offsetInBits = 0;
+      } else if (comp.type.value == android::gralloc4::PlaneLayoutComponentType_CB.value) {
+        comp.offsetInBits = 8;
+      } else {
+        return Error::BAD_VALUE;
+      }
+      break;
+    case static_cast<int32_t>(HAL_PIXEL_FORMAT_Y16):
+      if (comp.type.value == android::gralloc4::PlaneLayoutComponentType_Y.value) {
+        comp.offsetInBits = 0;
+        comp.sizeInBits = 16;
+      } else {
+        return Error::BAD_VALUE;
+      }
+      break;
+    case static_cast<int32_t>(HAL_PIXEL_FORMAT_YV12):
+      if (comp.type.value == android::gralloc4::PlaneLayoutComponentType_Y.value ||
+          comp.type.value == android::gralloc4::PlaneLayoutComponentType_CB.value ||
+          comp.type.value == android::gralloc4::PlaneLayoutComponentType_CR.value) {
+        comp.offsetInBits = 0;
+        comp.sizeInBits = 8;
+      } else {
+        return Error::BAD_VALUE;
+      }
+      break;
+    case static_cast<int32_t>(HAL_PIXEL_FORMAT_Y8):
+      if (comp.type.value == android::gralloc4::PlaneLayoutComponentType_Y.value) {
+        comp.offsetInBits = 0;
+        comp.sizeInBits = 8;
+      } else {
+        return Error::BAD_VALUE;
+      }
+      break;
+    case static_cast<int32_t>(HAL_PIXEL_FORMAT_YCbCr_420_P010):
+      if (comp.type.value == android::gralloc4::PlaneLayoutComponentType_Y.value ||
+          comp.type.value == android::gralloc4::PlaneLayoutComponentType_CB.value ||
+          comp.type.value == android::gralloc4::PlaneLayoutComponentType_CR.value) {
+        comp.offsetInBits = 0;
+        comp.sizeInBits = 10;
+      } else {
+        return Error::BAD_VALUE;
+      }
+      break;
+    case static_cast<int32_t>(HAL_PIXEL_FORMAT_YCbCr_420_P010_VENUS):
+      if (comp.type.value == android::gralloc4::PlaneLayoutComponentType_Y.value ||
+          comp.type.value == android::gralloc4::PlaneLayoutComponentType_CB.value) {
+        comp.offsetInBits = 6;
+        comp.sizeInBits = 10;
+      } else if (comp.type.value == android::gralloc4::PlaneLayoutComponentType_CR.value) {
+        comp.offsetInBits = 22;
+        comp.sizeInBits = 10;
+      } else {
+        return Error::BAD_VALUE;
+      }
+      break;
+
+    case static_cast<int32_t>(HAL_PIXEL_FORMAT_RAW16):
+      if (comp.type.value == android::gralloc4::PlaneLayoutComponentType_RAW.value) {
+        comp.offsetInBits = 0;
+        comp.sizeInBits = 16;
+      } else {
+        return Error::BAD_VALUE;
+      }
+      break;
+    case static_cast<int32_t>(HAL_PIXEL_FORMAT_RAW12):
+    case static_cast<int32_t>(HAL_PIXEL_FORMAT_RAW10):
+      if (comp.type.value == android::gralloc4::PlaneLayoutComponentType_RAW.value) {
+        comp.offsetInBits = 0;
+        comp.sizeInBits = -1;
+      } else {
+        return Error::BAD_VALUE;
+      }
+      break;
+    case static_cast<int32_t>(HAL_PIXEL_FORMAT_RAW8):
+      if (comp.type.value == android::gralloc4::PlaneLayoutComponentType_RAW.value) {
+        comp.offsetInBits = 0;
+        comp.sizeInBits = 8;
+      } else {
+        return Error::BAD_VALUE;
+      }
+      break;
+    default:
+      ALOGI("Offset and size in bits unknown for format %d", format);
+      return Error::UNSUPPORTED;
+  }
+  return Error::NONE;
+}
+
+static void grallocToStandardPlaneLayoutComponentType(uint32_t in,
+                                                      std::vector<PlaneLayoutComponent> *components,
+                                                      int32_t format) {
+  PlaneLayoutComponent comp;
+  comp.offsetInBits = -1;
+  comp.sizeInBits = -1;
+
+  if (in & PLANE_COMPONENT_Y) {
+    comp.type = android::gralloc4::PlaneLayoutComponentType_Y;
+    if (getComponentSizeAndOffset(format, comp) == Error::NONE)
+      components->push_back(comp);
+  }
+
+  if (in & PLANE_COMPONENT_Cb) {
+    comp.type = android::gralloc4::PlaneLayoutComponentType_CB;
+    if (getComponentSizeAndOffset(format, comp) == Error::NONE)
+      components->push_back(comp);
+  }
+
+  if (in & PLANE_COMPONENT_Cr) {
+    comp.type = android::gralloc4::PlaneLayoutComponentType_CR;
+    if (getComponentSizeAndOffset(format, comp) == Error::NONE)
+      components->push_back(comp);
+  }
+
+  if (in & PLANE_COMPONENT_R) {
+    comp.type = android::gralloc4::PlaneLayoutComponentType_R;
+    if (getComponentSizeAndOffset(format, comp) == Error::NONE)
+      components->push_back(comp);
+  }
+
+  if (in & PLANE_COMPONENT_G) {
+    comp.type = android::gralloc4::PlaneLayoutComponentType_G;
+    if (getComponentSizeAndOffset(format, comp) == Error::NONE)
+      components->push_back(comp);
+  }
+
+  if (in & PLANE_COMPONENT_B) {
+    comp.type = android::gralloc4::PlaneLayoutComponentType_B;
+    if (getComponentSizeAndOffset(format, comp) == Error::NONE)
+      components->push_back(comp);
+  }
+
+  if (in & PLANE_COMPONENT_A) {
+    comp.type = android::gralloc4::PlaneLayoutComponentType_A;
+    if (getComponentSizeAndOffset(format, comp) == Error::NONE)
+      components->push_back(comp);
+  }
+
+  if (in & PLANE_COMPONENT_RAW) {
+    comp.type = android::gralloc4::PlaneLayoutComponentType_RAW;
+    if (getComponentSizeAndOffset(format, comp) == Error::NONE)
+      components->push_back(comp);
+  }
+
+  if (in & PLANE_COMPONENT_META) {
+    comp.type = qtigralloc::PlaneLayoutComponentType_Meta;
+    components->push_back(comp);
+  }
+}
+
+Error GetPlaneLayout(private_handle_t *handle,
+                     std::vector<aidl::android::hardware::graphics::common::PlaneLayout> *out) {
+  std::vector<PlaneLayout> plane_info;
+  int plane_count = 0;
+  BufferInfo info(handle->unaligned_width, handle->unaligned_height, handle->format, handle->usage);
+
+  gralloc::PlaneLayoutInfo plane_layout[8] = {};
+  if (gralloc::IsYuvFormat(handle->format)) {
+    gralloc::GetYUVPlaneInfo(info, handle->format, handle->width, handle->height, handle->flags,
+                             &plane_count, plane_layout);
+  } else if (gralloc::IsUncompressedRGBFormat(handle->format) ||
+             gralloc::IsCompressedRGBFormat(handle->format)) {
+    gralloc::GetRGBPlaneInfo(info, handle->format, handle->width, handle->height, handle->flags,
+                             &plane_count, plane_layout);
+  } else {
+    return Error::BAD_BUFFER;
+  }
+  plane_info.resize(plane_count);
+  for (int i = 0; i < plane_count; i++) {
+    std::vector<PlaneLayoutComponent> components;
+    grallocToStandardPlaneLayoutComponentType(plane_layout[i].component, &plane_info[i].components,
+                                              handle->format);
+    plane_info[i].horizontalSubsampling = (1ull << plane_layout[i].h_subsampling);
+    plane_info[i].verticalSubsampling = (1ull << plane_layout[i].v_subsampling);
+    plane_info[i].offsetInBytes = static_cast<int64_t>(plane_layout[i].offset);
+    plane_info[i].sampleIncrementInBits = static_cast<int64_t>(plane_layout[i].step * 8);
+    plane_info[i].strideInBytes = static_cast<int64_t>(plane_layout[i].stride_bytes);
+    plane_info[i].totalSizeInBytes = static_cast<int64_t>(plane_layout[i].size);
+    plane_info[i].widthInSamples = handle->unaligned_width >> plane_layout[i].h_subsampling;
+    plane_info[i].heightInSamples = handle->unaligned_height >> plane_layout[i].v_subsampling;
+  }
+  *out = plane_info;
+  return Error::NONE;
+}
+
+Error GetMetaDataInternal(void *buffer, int64_t type, void *in, void **out) {
+  if (!in && !out) {
+    ALOGE("Invalid input params");
+    return Error::UNSUPPORTED;
+  }
+
+  private_handle_t *handle = static_cast<private_handle_t *>(buffer);
+  MetaData_t *data = reinterpret_cast<MetaData_t *>(handle->base_metadata);
+
+  int err = ValidateAndMap(handle);
+  if (err != 0) {
+    return Error::UNSUPPORTED;
+  }
+
+  // Make sure we send 0 only if the operation queried is present
+  auto ret = Error::BAD_VALUE;
+
+  if (data == nullptr) {
+    return ret;
+  }
+
+  bool copy = true;
+  if (in == nullptr) {
+    // Get by reference - do not check if metadata has been set
+    copy = false;
+  } else {
+    if (!getGralloc4Array(data, type)) {
+      return ret;
+    }
+  }
+
+  ret = Error::NONE;
+
+  switch (type) {
+    case QTI_PP_PARAM_INTERLACED:
+      if (copy) {
+        *(reinterpret_cast<int32_t *>(in)) = data->interlaced;
+      } else {
+        *out = &data->interlaced;
+      }
+      break;
+    case (int64_t)StandardMetadataType::CROP:
+      if (copy) {
+        *(reinterpret_cast<CropRectangle_t *>(in)) = data->crop;
+      }
+      break;
+    case QTI_REFRESH_RATE:
+      if (copy) {
+        *(reinterpret_cast<float *>(in)) = data->refreshrate;
+      } else {
+        *out = &data->refreshrate;
+      }
+      break;
+    case QTI_MAP_SECURE_BUFFER:
+      if (copy) {
+        *(reinterpret_cast<int32_t *>(in)) = data->mapSecureBuffer;
+      } else {
+        *out = &data->mapSecureBuffer;
+      }
+      break;
+    case QTI_LINEAR_FORMAT:
+      if (copy) {
+        *(reinterpret_cast<uint32_t *>(in)) = data->linearFormat;
+      } else {
+        *out = &data->linearFormat;
+      }
+      break;
+    case QTI_SINGLE_BUFFER_MODE:
+      if (copy) {
+        *(reinterpret_cast<uint32_t *>(in)) = data->isSingleBufferMode;
+      } else {
+        *out = &data->isSingleBufferMode;
+      }
+      break;
+    case QTI_VT_TIMESTAMP:
+      if (copy) {
+        *(reinterpret_cast<uint64_t *>(in)) = data->vtTimeStamp;
+      } else {
+        *out = &data->vtTimeStamp;
+      }
+      break;
+    case QTI_COLOR_METADATA:
+      if (copy) {
+        *(reinterpret_cast<ColorMetaData *>(in)) = data->color;
+      } else {
+        *out = &data->color;
+      }
+      break;
+    case QTI_UBWC_CR_STATS_INFO: {
+      if (copy) {
+        struct UBWCStats *stats = (struct UBWCStats *)in;
+        int numelems = sizeof(data->ubwcCRStats) / sizeof(struct UBWCStats);
+        for (int i = 0; i < numelems; i++) {
+          stats[i] = data->ubwcCRStats[i];
+        }
+      } else {
+        *out = &data->ubwcCRStats[0];
+      }
+      break;
+    }
+    case QTI_VIDEO_PERF_MODE:
+      if (copy) {
+        *(reinterpret_cast<uint32_t *>(in)) = data->isVideoPerfMode;
+      } else {
+        *out = &data->isVideoPerfMode;
+      }
+      break;
+    case QTI_GRAPHICS_METADATA:
+      if (copy) {
+        memcpy(in, data->graphics_metadata.data, sizeof(data->graphics_metadata.data));
+      } else {
+        *out = &data->graphics_metadata;
+      }
+      break;
+    case QTI_CVP_METADATA: {
+      if (copy) {
+        struct CVPMetadata *cvpMetadata = (struct CVPMetadata *)in;
+        cvpMetadata->size = 0;
+        if (data->cvpMetadata.size <= CVP_METADATA_SIZE) {
+          cvpMetadata->size = data->cvpMetadata.size;
+          memcpy(cvpMetadata->payload, data->cvpMetadata.payload, data->cvpMetadata.size);
+          cvpMetadata->capture_frame_rate = data->cvpMetadata.capture_frame_rate;
+          cvpMetadata->cvp_frame_rate = data->cvpMetadata.cvp_frame_rate;
+          cvpMetadata->flags = data->cvpMetadata.flags;
+          memcpy(cvpMetadata->reserved, data->cvpMetadata.reserved, (8 * sizeof(uint32_t)));
+        } else {
+          ret = Error::BAD_VALUE;
+        }
+      } else {
+        *out = &data->cvpMetadata;
+      }
+      break;
+    }
+    case QTI_VIDEO_HISTOGRAM_STATS: {
+      if (copy) {
+        struct VideoHistogramMetadata *vidstats = (struct VideoHistogramMetadata *)in;
+        vidstats->stat_len = 0;
+        if (data->video_histogram_stats.stat_len <= VIDEO_HISTOGRAM_STATS_SIZE) {
+          memcpy(vidstats->stats_info, data->video_histogram_stats.stats_info,
+                 VIDEO_HISTOGRAM_STATS_SIZE);
+          vidstats->stat_len = data->video_histogram_stats.stat_len;
+          vidstats->frame_type = data->video_histogram_stats.frame_type;
+          vidstats->display_width = data->video_histogram_stats.display_width;
+          vidstats->display_height = data->video_histogram_stats.display_height;
+          vidstats->decode_width = data->video_histogram_stats.decode_width;
+          vidstats->decode_height = data->video_histogram_stats.decode_height;
+        } else {
+          ret = Error::BAD_VALUE;
+        }
+      } else {
+        *out = &data->video_histogram_stats;
+      }
+      break;
+    }
+    case QTI_VIDEO_TS_INFO:
+      if (copy) {
+        *(reinterpret_cast<VideoTimestampInfo *>(in)) = data->videoTsInfo;
+      } else {
+        *out = &data->videoTsInfo;
+      }
+      break;
+    case (int64_t)StandardMetadataType::BUFFER_ID:
+      if (copy) {
+        *(reinterpret_cast<uint64_t *>(in)) = (uint64_t)handle->id;
+      } else {
+        *out = &handle->id;
+      }
+      break;
+    case (int64_t)StandardMetadataType::NAME: {
+      if (copy) {
+        std::string name(data->name);
+        *(reinterpret_cast<std::string *>(in)) = name;
+      } else {
+        *out = &data->name;
+      }
+      break;
+    }
+    case (int64_t)StandardMetadataType::WIDTH:
+      if (copy) {
+        *(reinterpret_cast<uint64_t *>(in)) = (uint64_t)handle->unaligned_width;
+      } else {
+        *out = &handle->unaligned_width;
+      }
+      break;
+    case (int64_t)StandardMetadataType::HEIGHT:
+      if (copy) {
+        *(reinterpret_cast<uint64_t *>(in)) = (uint64_t)handle->unaligned_height;
+      } else {
+        *out = &handle->unaligned_height;
+      }
+      break;
+    case (int64_t)StandardMetadataType::LAYER_COUNT:
+      if (copy) {
+        *(reinterpret_cast<uint64_t *>(in)) = (uint64_t)handle->layer_count;
+      } else {
+        *out = &handle->layer_count;
+      }
+      break;
+    case (int64_t)StandardMetadataType::PIXEL_FORMAT_REQUESTED:
+      if (copy) {
+        *(reinterpret_cast<PixelFormat *>(in)) = (PixelFormat)handle->format;
+      } else {
+        *out = &handle->format;
+      }
+      break;
+    case (int64_t)StandardMetadataType::USAGE:
+      if (copy) {
+        *(reinterpret_cast<uint64_t *>(in)) = (uint64_t)handle->usage;
+      } else {
+        *out = &handle->usage;
+      }
+      break;
+    case (int64_t)StandardMetadataType::PIXEL_FORMAT_FOURCC: {
+      if (copy) {
+        uint32_t drm_format = 0;
+        uint64_t drm_format_modifier = 0;
+        GetDRMFormat(handle->format, handle->flags, &drm_format, &drm_format_modifier);
+        *(reinterpret_cast<uint32_t *>(in)) = drm_format;
+      }
+      break;
+    }
+    case (int64_t)StandardMetadataType::PIXEL_FORMAT_MODIFIER: {
+      if (copy) {
+        uint32_t drm_format = 0;
+        uint64_t drm_format_modifier = 0;
+        GetDRMFormat(handle->format, handle->flags, &drm_format, &drm_format_modifier);
+        *(reinterpret_cast<uint64_t *>(in)) = drm_format_modifier;
+      }
+      break;
+    }
+    case (int64_t)StandardMetadataType::PROTECTED_CONTENT: {
+      if (copy) {
+        uint64_t protected_content = (handle->flags & qtigralloc::PRIV_FLAGS_SECURE_BUFFER) ? 1 : 0;
+        *(reinterpret_cast<uint64_t *>(in)) = protected_content;
+      }
+      break;
+    }
+    case (int64_t)StandardMetadataType::ALLOCATION_SIZE:
+      if (copy) {
+        *(reinterpret_cast<uint64_t *>(in)) = (uint64_t)handle->size;
+      } else {
+        *out = &handle->size;
+      }
+      break;
+    case QTI_FD:
+      if (copy) {
+        *(reinterpret_cast<int32_t *>(in)) = handle->fd;
+      } else {
+        *out = &handle->fd;
+      }
+      break;
+    case QTI_PRIVATE_FLAGS:
+      if (copy) {
+        *(reinterpret_cast<uint32_t *>(in)) = handle->flags;
+      } else {
+        *out = &handle->flags;
+      }
+      break;
+    case QTI_ALIGNED_WIDTH_IN_PIXELS:
+      if (copy) {
+        *(reinterpret_cast<uint32_t *>(in)) = handle->width;
+      } else {
+        *out = &handle->width;
+      }
+      break;
+    case QTI_ALIGNED_HEIGHT_IN_PIXELS:
+      if (copy) {
+        *(reinterpret_cast<uint32_t *>(in)) = handle->height;
+      } else {
+        *out = &handle->height;
+      }
+      break;
+    case QTI_COLORSPACE: {
+      if (copy) {
+        uint32_t colorspace;
+        auto error = GetColorSpaceFromColorMetaData(data->color, &colorspace);
+        if (error == Error::NONE) {
+          *(reinterpret_cast<uint32_t *>(in)) = colorspace;
+          break;
+        } else {
+          ret = Error::BAD_VALUE;
+          break;
+        }
+      }
+    }
+    case QTI_YUV_PLANE_INFO: {
+      if (copy) {
+        qti_ycbcr layout[2];
+        android_ycbcr yuv_plane_info[2];
+        int error = GetYUVPlaneInfo(handle, yuv_plane_info);
+        if (!error) {
+          for (int i = 0; i < 2; i++) {
+            layout[i].y = yuv_plane_info[i].y;
+            layout[i].cr = yuv_plane_info[i].cr;
+            layout[i].cb = yuv_plane_info[i].cb;
+            layout[i].yStride = static_cast<uint32_t>(yuv_plane_info[i].ystride);
+            layout[i].cStride = static_cast<uint32_t>(yuv_plane_info[i].cstride);
+            layout[i].chromaStep = static_cast<uint32_t>(yuv_plane_info[i].chroma_step);
+          }
+
+          uint64_t yOffset = (reinterpret_cast<uint64_t>(layout[0].y) - handle->base);
+          uint64_t crOffset = (reinterpret_cast<uint64_t>(layout[0].cr) - handle->base);
+          uint64_t cbOffset = (reinterpret_cast<uint64_t>(layout[0].cb) - handle->base);
+          ALOGD(" layout: y: %" PRIu64 " , cr: %" PRIu64 " , cb: %" PRIu64
+                " , yStride: %d, cStride: %d, chromaStep: %d ",
+                yOffset, crOffset, cbOffset, layout[0].yStride, layout[0].cStride,
+                layout[0].chromaStep);
+
+          memcpy(in, layout, YCBCR_LAYOUT_ARRAY_SIZE * sizeof(qti_ycbcr));
+          break;
+        } else {
+          ret = Error::BAD_BUFFER;
+          break;
+        }
+      }
+      break;
+    }
+    case QTI_CUSTOM_DIMENSIONS_STRIDE: {
+      if (copy) {
+        int32_t stride;
+        int32_t height;
+        if (GetCustomDimensions(handle, &stride, &height) == 0) {
+          *(reinterpret_cast<int32_t *>(in)) = stride;
+          break;
+        } else {
+          ret = Error::BAD_VALUE;
+          break;
+        }
+      }
+    }
+    case QTI_CUSTOM_DIMENSIONS_HEIGHT: {
+      if (copy) {
+        int32_t stride = handle->width;
+        int32_t height = handle->height;
+        if (GetCustomDimensions(handle, &stride, &height) == 0) {
+          *(reinterpret_cast<int32_t *>(in)) = height;
+          break;
+        } else {
+          ret = Error::BAD_VALUE;
+          break;
+        }
+      }
+    }
+    case QTI_RGB_DATA_ADDRESS: {
+      if (copy) {
+        void *rgb_data = nullptr;
+        if (GetRgbDataAddress(handle, &rgb_data) == 0) {
+          *(reinterpret_cast<void **>(in)) = rgb_data;
+          break;
+        } else {
+          ret = Error::BAD_BUFFER;
+          break;
+        }
+      }
+    }
+    case QTI_BUFFER_TYPE:
+      if (copy) {
+        *(reinterpret_cast<uint32_t *>(in)) = handle->buffer_type;
+      } else {
+        *out = &handle->buffer_type;
+      }
+      break;
+    case QTI_STANDARD_METADATA_STATUS:
+      if (copy) {
+        memcpy(in, data->isStandardMetadataSet, sizeof(bool) * METADATA_SET_SIZE);
+      } else {
+        *out = &data->isStandardMetadataSet;
+      }
+      break;
+    case QTI_VENDOR_METADATA_STATUS:
+      if (copy) {
+        memcpy(in, data->isVendorMetadataSet, sizeof(bool) * METADATA_SET_SIZE);
+      } else {
+        *out = &data->isVendorMetadataSet;
+      }
+      break;
+    case (int64_t)StandardMetadataType::DATASPACE: {
+      if (copy) {
+        if (data->isStandardMetadataSet[GET_STANDARD_METADATA_STATUS_INDEX(type)]) {
+          Dataspace dataspace;
+          ColorMetadataToDataspace(data->color, &dataspace);
+          *(reinterpret_cast<Dataspace *>(in)) = dataspace;
+        } else {
+          *(reinterpret_cast<Dataspace *>(in)) = Dataspace::UNKNOWN;
+        }
+      }
+      break;
+    }
+    case (int64_t)StandardMetadataType::BLEND_MODE:
+      if (copy) {
+        *(reinterpret_cast<int32_t *>(in)) = data->blendMode;
+      } else {
+        *out = &data->blendMode;
+      }
+      break;
+    case (int64_t)StandardMetadataType::PLANE_LAYOUTS:
+      if (copy) {
+        std::vector<PlaneLayout> *plane_layouts = reinterpret_cast<std::vector<PlaneLayout> *>(in);
+        GetPlaneLayout(handle, plane_layouts);
+      }
+      break;
+    default:
+      ALOGE("Unknown metadata type %d", type);
+      ret = Error::BAD_VALUE;
+      break;
+  }
+
+  return ret;
+}
+
 }  // namespace gralloc
diff --git a/gralloc/gr_utils.h b/gralloc/gr_utils.h
index 093d765..9fcc312 100644
--- a/gralloc/gr_utils.h
+++ b/gralloc/gr_utils.h
@@ -31,9 +31,11 @@
 #define __GR_UTILS_H__
 
 #include <android/hardware/graphics/common/1.2/types.h>
-
+#include <gralloctypes/Gralloc4.h>
 #include <limits>
+#include <vector>
 
+#include "QtiGrallocPriv.h"
 #include "gralloc_priv.h"
 #include "qdMetaData.h"
 
@@ -234,6 +236,18 @@
 void GetDRMFormat(uint32_t format, uint32_t flags, uint32_t *drm_format,
                   uint64_t *drm_format_modifier);
 bool CanAllocateZSLForSecureCamera();
+
+uint64_t GetMetaDataSize(uint64_t reserved_region_size);
+void UnmapAndReset(private_handle_t *handle, uint64_t reserved_region_size = 0);
+int ValidateAndMap(private_handle_t *handle, uint64_t reserved_region_size = 0);
+Error GetColorSpaceFromColorMetaData(ColorMetaData color_metadata, uint32_t *color_space);
+Error GetMetaDataByReference(void *buffer, int64_t type, void **out);
+Error GetMetaDataValue(void *buffer, int64_t type, void *in);
+Error GetMetaDataInternal(void *buffer, int64_t type, void *in, void **out);
+Error ColorMetadataToDataspace(ColorMetaData color_metadata,
+                               aidl::android::hardware::graphics::common::Dataspace *dataspace);
+Error GetPlaneLayout(private_handle_t *handle,
+                     std::vector<aidl::android::hardware::graphics::common::PlaneLayout> *out);
 }  // namespace gralloc
 
 #endif  // __GR_UTILS_H__