mm-video-v4l2: vidc: Fix read/write colorspace from/to gralloc-handle

Encoder:
Read the colorspace from metadata in gralloc-handle and
set the appropriate colorspace to the driver.

Recommend color-aspects based on the colorspace of destination-YUV
that C2D/Venus convert in case input is RGBA8888

Leave the unspecified aspects with client's-defaults, rather
than setting them to enuemarated "unspecified" values.

Decoder:
Default the colorspace as indicated by client in case there is
no color info in bitstream. Since VP8 encoder does not support
encoding color-info yet, default everything to 601-LR for now.

Bug: 29550317
Change-Id: I603cd592647b3f9b81c4da714a72aae871ced25a
diff --git a/msm8996/mm-video-v4l2/vidc/vdec/inc/omx_vdec.h b/msm8996/mm-video-v4l2/vidc/vdec/inc/omx_vdec.h
index 789b08c..d400fc3 100644
--- a/msm8996/mm-video-v4l2/vidc/vdec/inc/omx_vdec.h
+++ b/msm8996/mm-video-v4l2/vidc/vdec/inc/omx_vdec.h
@@ -670,6 +670,7 @@
             OMX_U32 transfer, OMX_U32 matrix, ColorSpace_t *color_space,
             ColorAspects *aspects);
         void handle_color_space_info(void *data, unsigned int buf_index);
+        void set_colorspace_in_handle(ColorSpace_t color, unsigned int buf_index);
         void print_debug_color_aspects(ColorAspects *aspects, const char *prefix);
         void print_debug_extradata(OMX_OTHER_EXTRADATATYPE *extra);
 #ifdef _MSM8974_
diff --git a/msm8996/mm-video-v4l2/vidc/vdec/src/omx_vdec_v4l2.cpp b/msm8996/mm-video-v4l2/vidc/vdec/src/omx_vdec_v4l2.cpp
index bbe6a1e..25c6b5d 100644
--- a/msm8996/mm-video-v4l2/vidc/vdec/src/omx_vdec_v4l2.cpp
+++ b/msm8996/mm-video-v4l2/vidc/vdec/src/omx_vdec_v4l2.cpp
@@ -7978,6 +7978,42 @@
     }
 
     if (!output_flush_progress && (buffer->nFilledLen > 0)) {
+        // set the default colorspace advised by client, since the bitstream may be
+        // devoid of colorspace-info.
+        if (m_enable_android_native_buffers) {
+            ColorSpace_t color_space = ITU_R_601;
+
+        // Disabled ?
+        // WA for VP8. Vp8 encoder does not embed color-info (yet!).
+        // Encoding RGBA results in 601-LR for all resolutions.
+        // This conflicts with the client't defaults which are based on resolution.
+        //   Eg: 720p will be encoded as 601-LR. Client will say 709.
+        // Re-enable this code once vp8 encoder generates color-info and hence the
+        // decoder will be able to override with the correct source color.
+#if 0
+            switch (m_client_color_space.sAspects.mPrimaries) {
+                case ColorAspects::PrimariesBT601_6_625:
+                case ColorAspects::PrimariesBT601_6_525:
+                {
+                    color_space = m_client_color_space.sAspects.mRange == ColorAspects::RangeFull ?
+                            ITU_R_601_FR : ITU_R_601;
+                    break;
+                }
+                case ColorAspects::PrimariesBT709_5:
+                {
+                    color_space = ITU_R_709;
+                    break;
+                }
+                default:
+                {
+                    break;
+                }
+            }
+#endif
+            DEBUG_PRINT_LOW("setMetaData for Color Space (client) = 0x%x (601=%u FR=%u 709=%u)",
+                    color_space, ITU_R_601, ITU_R_601_FR, ITU_R_709);
+            set_colorspace_in_handle(color_space, buffer - m_out_mem_ptr);
+        }
         DEBUG_PRINT_LOW("Processing extradata");
         handle_extradata(buffer);
     }
@@ -10255,9 +10291,8 @@
             break;
     }
     if (m_enable_android_native_buffers) {
-        DEBUG_PRINT_HIGH("setMetaData for Color Space = 0x%x", color_space);
-        setMetaData((private_handle_t *)native_buffer[buf_index].privatehandle,
-                UPDATE_COLOR_SPACE, (void*)&color_space);
+        DEBUG_PRINT_HIGH("setMetaData for Color Space = 0x%x (601=%u FR=%u 709=%u)", color_space, ITU_R_601, ITU_R_601_FR, ITU_R_709);
+        set_colorspace_in_handle(color_space, buf_index);
     }
     print_debug_color_aspects(aspects, "Bitstream");
 
@@ -10278,6 +10313,18 @@
     }
 }
 
+void omx_vdec::set_colorspace_in_handle(ColorSpace_t color_space, unsigned int buf_index) {
+    private_handle_t *private_handle = NULL;
+    if (buf_index < drv_ctx.op_buf.actualcount &&
+            buf_index < MAX_NUM_INPUT_OUTPUT_BUFFERS &&
+            native_buffer[buf_index].privatehandle) {
+        private_handle = native_buffer[buf_index].privatehandle;
+    }
+    if (private_handle) {
+        setMetaData(private_handle, UPDATE_COLOR_SPACE, (void*)&color_space);
+    }
+}
+
 void omx_vdec::handle_extradata(OMX_BUFFERHEADERTYPE *p_buf_hdr)
 {
     OMX_OTHER_EXTRADATATYPE *p_extra = NULL, *p_sei = NULL, *p_vui = NULL;
diff --git a/msm8996/mm-video-v4l2/vidc/venc/Android.mk b/msm8996/mm-video-v4l2/vidc/venc/Android.mk
index d71e1eb..25e9601 100644
--- a/msm8996/mm-video-v4l2/vidc/venc/Android.mk
+++ b/msm8996/mm-video-v4l2/vidc/venc/Android.mk
@@ -89,6 +89,7 @@
 LOCAL_PRELINK_MODULE      := false
 LOCAL_SHARED_LIBRARIES    := liblog libutils libbinder libcutils \
                              libc2dcolorconvert libdl libgui
+LOCAL_SHARED_LIBRARIES    += libqdMetaData
 LOCAL_STATIC_LIBRARIES    := libOmxVidcCommon
 
 LOCAL_SRC_FILES   := src/omx_video_base.cpp
diff --git a/msm8996/mm-video-v4l2/vidc/venc/inc/omx_video_base.h b/msm8996/mm-video-v4l2/vidc/venc/inc/omx_video_base.h
index 4ded11f..351c011 100644
--- a/msm8996/mm-video-v4l2/vidc/venc/inc/omx_video_base.h
+++ b/msm8996/mm-video-v4l2/vidc/venc/inc/omx_video_base.h
@@ -563,6 +563,7 @@
 
         void complete_pending_buffer_done_cbs();
         bool is_conv_needed(int, int);
+        void print_debug_color_aspects(ColorAspects *aspects, const char *prefix);
 
 #ifdef USE_ION
         int alloc_map_ion_memory(int size,
diff --git a/msm8996/mm-video-v4l2/vidc/venc/src/omx_video_base.cpp b/msm8996/mm-video-v4l2/vidc/venc/src/omx_video_base.cpp
index 11286a9..c296f4f 100644
--- a/msm8996/mm-video-v4l2/vidc/venc/src/omx_video_base.cpp
+++ b/msm8996/mm-video-v4l2/vidc/venc/src/omx_video_base.cpp
@@ -2259,7 +2259,27 @@
                     DEBUG_PRINT_ERROR("Does not handle dataspace request");
                     return OMX_ErrorUnsupportedSetting;
                 }
-                memcpy(pParam, &m_sConfigColorAspects, sizeof(m_sConfigColorAspects));
+                if (pParam->bDataSpaceChanged == OMX_TRUE) {
+
+                    print_debug_color_aspects(&(pParam->sAspects), "get_config (dataspace changed) Client says");
+                    // If the dataspace says RGB, recommend 601-limited;
+                    // since that is the destination colorspace that C2D or Venus will convert to.
+                    if (pParam->nPixelFormat == HAL_PIXEL_FORMAT_RGBA_8888) {
+                        DEBUG_PRINT_INFO("get_config (dataspace changed): ColorSpace: Recommend 601-limited for RGBA8888");
+                        pParam->sAspects.mPrimaries = ColorAspects::PrimariesBT601_6_625;
+                        pParam->sAspects.mRange = ColorAspects::RangeLimited;
+                        pParam->sAspects.mTransfer = ColorAspects::TransferSMPTE170M;
+                        pParam->sAspects.mMatrixCoeffs = ColorAspects::MatrixBT601_6;
+                    } else {
+                        // For IMPLEMENTATION_DEFINED (or anything else), stick to client's defaults.
+                        DEBUG_PRINT_INFO("get_config (dataspace changed): ColorSpace: use client-default for format=%x",
+                                pParam->nPixelFormat);
+                    }
+                    print_debug_color_aspects(&(pParam->sAspects), "get_config (dataspace changed) recommended");
+                } else {
+                    memcpy(pParam, &m_sConfigColorAspects, sizeof(m_sConfigColorAspects));
+                    print_debug_color_aspects(&(pParam->sAspects), "get_config");
+                }
                 break;
             }
         default:
@@ -4922,6 +4942,11 @@
     return bRet;
 }
 
+void omx_video::print_debug_color_aspects(ColorAspects *aspects, const char *prefix) {
+    DEBUG_PRINT_HIGH("%s : Color aspects : Primaries = %d Range = %d Transfer = %d MatrixCoeffs = %d",
+            prefix, aspects->mPrimaries, aspects->mRange, aspects->mTransfer, aspects->mMatrixCoeffs);
+}
+
 OMX_ERRORTYPE  omx_video::empty_this_buffer_opaque(OMX_IN OMX_HANDLETYPE hComp,
         OMX_IN OMX_BUFFERHEADERTYPE* buffer)
 {
diff --git a/msm8996/mm-video-v4l2/vidc/venc/src/omx_video_encoder.cpp b/msm8996/mm-video-v4l2/vidc/venc/src/omx_video_encoder.cpp
index b97eedc..ceacf19 100644
--- a/msm8996/mm-video-v4l2/vidc/venc/src/omx_video_encoder.cpp
+++ b/msm8996/mm-video-v4l2/vidc/venc/src/omx_video_encoder.cpp
@@ -2095,6 +2095,8 @@
         case OMX_QTIIndexConfigDescribeColorAspects:
            {
                VALIDATE_OMX_PARAM_DATA(configData, DescribeColorAspectsParams);
+               DescribeColorAspectsParams *params = (DescribeColorAspectsParams *)configData;
+               print_debug_color_aspects(&(params->sAspects), "set_config");
                if (!handle->venc_set_config(configData, (OMX_INDEXTYPE)OMX_QTIIndexConfigDescribeColorAspects)) {
                    DEBUG_PRINT_ERROR("Failed to set OMX_QTIIndexConfigDescribeColorAspects");
                    return OMX_ErrorUnsupportedSetting;
diff --git a/msm8996/mm-video-v4l2/vidc/venc/src/video_encoder_device_v4l2.cpp b/msm8996/mm-video-v4l2/vidc/venc/src/video_encoder_device_v4l2.cpp
index c34d9a7..76bd24a 100644
--- a/msm8996/mm-video-v4l2/vidc/venc/src/video_encoder_device_v4l2.cpp
+++ b/msm8996/mm-video-v4l2/vidc/venc/src/video_encoder_device_v4l2.cpp
@@ -2625,21 +2625,16 @@
         case OMX_QTIIndexConfigDescribeColorAspects:
             {
                 DescribeColorAspectsParams *params = (DescribeColorAspectsParams *)configData;
-                DEBUG_PRINT_LOW("OMX_QTIIndexConfigDescribeColorAspects : sAspects.mPrimaries  = %d sAspects.mRange = %d"
-                    "sAspects.mTransfer %d, sAspects.mMatrixCoeffs = %d", params->sAspects.mPrimaries, params->sAspects.mRange,
-                    params->sAspects.mTransfer, params->sAspects.mMatrixCoeffs);
-                OMX_U32 color_space = MSM_VIDC_BT601_6_525;
-                OMX_U32 full_range = 1;
-                OMX_U32 matrix_coeffs = MSM_VIDC_MATRIX_601_6_525;
-                OMX_U32 transfer_chars = MSM_VIDC_TRANSFER_601_6_525;
+
+                OMX_U32 color_space = MSM_VIDC_BT601_6_625;
+                OMX_U32 full_range = 0;
+                OMX_U32 matrix_coeffs = MSM_VIDC_MATRIX_601_6_625;
+                OMX_U32 transfer_chars = MSM_VIDC_TRANSFER_601_6_625;
 
                 switch((ColorAspects::Primaries)(params->sAspects.mPrimaries)) {
                     case ColorAspects::PrimariesBT709_5:
                         color_space = MSM_VIDC_BT709_5;
                         break;
-                    case ColorAspects::PrimariesUnspecified:
-                        color_space = MSM_VIDC_UNSPECIFIED;
-                        break;
                     case ColorAspects::PrimariesBT470_6M:
                         color_space = MSM_VIDC_BT470_6_M;
                         break;
@@ -2656,8 +2651,8 @@
                         color_space = MSM_VIDC_BT2020;
                         break;
                     default:
-                        color_space = MSM_VIDC_BT601_6_525;
-                        params->sAspects.mPrimaries = ColorAspects::PrimariesBT601_6_525;
+                        color_space = MSM_VIDC_BT601_6_625;
+                        //params->sAspects.mPrimaries = ColorAspects::PrimariesBT601_6_625;
                         break;
                 }
                 switch((ColorAspects::Range)params->sAspects.mRange) {
@@ -2699,8 +2694,8 @@
                         transfer_chars = MSM_VIDC_TRANSFER_SRGB;
                         break;
                     default:
-                        params->sAspects.mTransfer = ColorAspects::TransferSMPTE170M;
-                        transfer_chars = MSM_VIDC_TRANSFER_601_6_525;
+                        //params->sAspects.mTransfer = ColorAspects::TransferSMPTE170M;
+                        transfer_chars = MSM_VIDC_TRANSFER_601_6_625;
                         break;
                 }
                 switch((ColorAspects::MatrixCoeffs)params->sAspects.mMatrixCoeffs) {
@@ -2726,8 +2721,8 @@
                         matrix_coeffs = MSM_VIDC_MATRIX_BT_2020_CONST;
                         break;
                     default:
-                        params->sAspects.mMatrixCoeffs = ColorAspects::MatrixBT601_6;
-                        matrix_coeffs = MSM_VIDC_MATRIX_601_6_525;
+                        //params->sAspects.mMatrixCoeffs = ColorAspects::MatrixBT601_6;
+                        matrix_coeffs = MSM_VIDC_MATRIX_601_6_625;
                         break;
                 }
                 if (!venc_set_colorspace(color_space, full_range,
@@ -3506,55 +3501,93 @@
                             fd, plane[0].bytesused, plane[0].length, buf.flags, m_sVenc_cfg.inputformat);
                 } else if (meta_buf->buffer_type == kMetadataBufferTypeGrallocSource) {
                     private_handle_t *handle = (private_handle_t *)meta_buf->meta_handle;
-                    if (!streaming[OUTPUT_PORT]) {
+                    if (!streaming[OUTPUT_PORT] && handle) {
+
+                        // Moment of truth... actual colorspace is known here..
+                        ColorSpace_t colorSpace = ITU_R_601;
+                        if (getMetaData(handle, GET_COLOR_SPACE, &colorSpace) == 0) {
+                            DEBUG_PRINT_INFO("ENC_CONFIG: gralloc ColorSpace = %d (601=%d 601_FR=%d 709=%d)",
+                                    colorSpace, ITU_R_601, ITU_R_601_FR, ITU_R_709);
+                        }
+
                         struct v4l2_format fmt;
-                        int color_space = 0;
-
                         memset(&fmt, 0, sizeof(fmt));
-
                         fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
+
+                        bool isUBWC = (handle->flags & private_handle_t::PRIV_FLAGS_UBWC_ALIGNED) && is_gralloc_source_ubwc;
                         if (handle->format == HAL_PIXEL_FORMAT_NV12_ENCODEABLE) {
-                            if ((handle->flags & private_handle_t::PRIV_FLAGS_UBWC_ALIGNED) &&
-                                    is_gralloc_source_ubwc) {
-                                m_sVenc_cfg.inputformat = V4L2_PIX_FMT_NV12_UBWC;
-                            } else {
-                                m_sVenc_cfg.inputformat = V4L2_PIX_FMT_NV12;
-                            }
+                            m_sVenc_cfg.inputformat = isUBWC ? V4L2_PIX_FMT_NV12_UBWC : V4L2_PIX_FMT_NV12;
+                            DEBUG_PRINT_INFO("ENC_CONFIG: Input Color = NV12 %s", isUBWC ? "UBWC" : "Linear");
                         } else if (handle->format == HAL_PIXEL_FORMAT_RGBA_8888) {
-                            if ((handle->flags & private_handle_t::PRIV_FLAGS_UBWC_ALIGNED) &&
-                                    is_gralloc_source_ubwc) {
-                                m_sVenc_cfg.inputformat = V4L2_PIX_FMT_RGBA8888_UBWC;
-                            } else {
-                                m_sVenc_cfg.inputformat = V4L2_PIX_FMT_RGB32;
-                            }
-                        } else if (  handle->format == QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m) {
+                            // In case of RGB, conversion to YUV is handled within encoder.
+                            // Disregard the Colorspace in gralloc-handle in case of RGB and use
+                            //   [a] 601 for non-UBWC case : C2D output is (apparently) 601-LR
+                            //   [b] 601 for UBWC case     : Venus can convert to 601-LR or FR. use LR for now.
+                            colorSpace = ITU_R_601;
+                            m_sVenc_cfg.inputformat = isUBWC ? V4L2_PIX_FMT_RGBA8888_UBWC : V4L2_PIX_FMT_RGB32;
+                            DEBUG_PRINT_INFO("ENC_CONFIG: Input Color = RGBA8888 %s", isUBWC ? "UBWC" : "Linear");
+                        } else if (handle->format == QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m) {
                             m_sVenc_cfg.inputformat = V4L2_PIX_FMT_NV12;
+                            DEBUG_PRINT_INFO("ENC_CONFIG: Input Color = NV12 Linear");
                         }
-                        if (handle->flags & private_handle_t::PRIV_FLAGS_ITU_R_709) {
-                            buf.flags = V4L2_MSM_BUF_FLAG_YUV_601_709_CLAMP;
-                            color_space = V4L2_COLORSPACE_REC709;
-                            venc_set_colorspace(MSM_VIDC_BT709_5, 1,
-                                    MSM_VIDC_TRANSFER_BT709_5, MSM_VIDC_MATRIX_BT_709_5);
-                        } else {
-                            if (is_csc_enabled) {
-                                struct v4l2_control control;
-                                control.id = V4L2_CID_MPEG_VIDC_VIDEO_VPE_CSC;
-                                control.value = V4L2_CID_MPEG_VIDC_VIDEO_VPE_CSC_ENABLE;
-                                if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
-                                    DEBUG_PRINT_ERROR("Failed to set VPE CSC for 601_to_709");
-                                }
-                                buf.flags = V4L2_MSM_BUF_FLAG_YUV_601_709_CLAMP;
-                                fmt.fmt.pix_mp.colorspace = V4L2_COLORSPACE_REC709;
-                                venc_set_colorspace(MSM_VIDC_BT709_5, 1,
-                                        MSM_VIDC_TRANSFER_BT709_5, MSM_VIDC_MATRIX_BT_709_5);
+
+                        // If device recommendation (persist.vidc.enc.csc.enable) is to use 709, force CSC
+                        if (colorSpace == ITU_R_601_FR && is_csc_enabled) {
+                            struct v4l2_control control;
+                            control.id = V4L2_CID_MPEG_VIDC_VIDEO_VPE_CSC;
+                            control.value = V4L2_CID_MPEG_VIDC_VIDEO_VPE_CSC_ENABLE;
+                            if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
+                                DEBUG_PRINT_ERROR("venc_empty_buf: Failed to set VPE CSC for 601_to_709");
                             } else {
-                                venc_set_colorspace(MSM_VIDC_BT601_6_525, 1,
-                                        MSM_VIDC_TRANSFER_601_6_525, MSM_VIDC_MATRIX_601_6_525);
-                                fmt.fmt.pix_mp.colorspace = V4L2_COLORSPACE_470_SYSTEM_BG;
+                                DEBUG_PRINT_INFO("venc_empty_buf: Will convert 601-FR to 709");
+                                buf.flags = V4L2_MSM_BUF_FLAG_YUV_601_709_CLAMP;
+                                colorSpace = ITU_R_709;
                             }
                         }
+
+                        msm_vidc_h264_color_primaries_values primary;
+                        msm_vidc_h264_transfer_chars_values transfer;
+                        msm_vidc_h264_matrix_coeff_values matrix;
+                        OMX_U32 range;
+
+                        switch (colorSpace) {
+                            case ITU_R_601_FR:
+                            {
+                                primary = MSM_VIDC_BT601_6_525;
+                                range = 1; // full
+                                transfer = MSM_VIDC_TRANSFER_601_6_525;
+                                matrix = MSM_VIDC_MATRIX_601_6_525;
+
+                                fmt.fmt.pix_mp.colorspace = V4L2_COLORSPACE_470_SYSTEM_BG;
+                                break;
+                            }
+                            case ITU_R_709:
+                            {
+                                primary = MSM_VIDC_BT709_5;
+                                range = 0; // limited
+                                transfer = MSM_VIDC_TRANSFER_BT709_5;
+                                matrix = MSM_VIDC_MATRIX_BT_709_5;
+
+                                fmt.fmt.pix_mp.colorspace = V4L2_COLORSPACE_REC709;
+                                break;
+                            }
+                            default:
+                            {
+                                // 601 or something else ? assume 601
+                                primary = MSM_VIDC_BT601_6_625;
+                                range = 0; //limited
+                                transfer = MSM_VIDC_TRANSFER_601_6_625;
+                                matrix = MSM_VIDC_MATRIX_601_6_625;
+
+                                fmt.fmt.pix_mp.colorspace = V4L2_COLORSPACE_470_SYSTEM_BG;
+                                break;
+                            }
+                        }
+                        DEBUG_PRINT_INFO("ENC_CONFIG: selected ColorSpace = %d (601=%d 601_FR=%d 709=%d)",
+                                    colorSpace, ITU_R_601, ITU_R_601_FR, ITU_R_709);
+                        venc_set_colorspace(primary, range, transfer, matrix);
+
                         fmt.fmt.pix_mp.pixelformat = m_sVenc_cfg.inputformat;
-                        fmt.fmt.pix_mp.colorspace = static_cast<decltype(fmt.fmt.pix_mp.colorspace)>(color_space);
                         fmt.fmt.pix_mp.height = m_sVenc_cfg.input_height;
                         fmt.fmt.pix_mp.width = m_sVenc_cfg.input_width;
                         if (ioctl(m_nDriver_fd, VIDIOC_S_FMT, &fmt)) {