Merge "gralloc1: Add support to provide interlace info"
diff --git a/libgralloc1/gr_buf_mgr.cpp b/libgralloc1/gr_buf_mgr.cpp
index 743c1c2..7e0ba14 100644
--- a/libgralloc1/gr_buf_mgr.cpp
+++ b/libgralloc1/gr_buf_mgr.cpp
@@ -771,6 +771,17 @@
       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 aee8c0d..b3056e1 100644
--- a/libgralloc1/gr_utils.cpp
+++ b/libgralloc1/gr_utils.cpp
@@ -311,6 +311,28 @@
   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<uint64_t>(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 @@
   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<MetaData_t *>(hnd->base_metadata);
@@ -354,6 +377,11 @@
     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 @@
       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 aa66fd0..2a08539 100644
--- a/libgralloc1/gr_utils.h
+++ b/libgralloc1/gr_utils.h
@@ -83,6 +83,8 @@
                        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 ba156b6..1839d2f 100644
--- a/libgralloc1/gralloc_priv.h
+++ b/libgralloc1/gralloc_priv.h
@@ -97,6 +97,7 @@
 #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