mm-video-v4l2: New extradata for hdr10 plus metadata

Using this extradata, clients can provided packed metadata
for each frame.This will be included in the encoded bitstream.

CRs-Fixed: 2321404
Change-Id: I335dc3bd21fa7fce53dd161fe417c7e63be329a3
diff --git a/mm-video-v4l2/vidc/venc/inc/video_encoder_device_v4l2.h b/mm-video-v4l2/vidc/venc/inc/video_encoder_device_v4l2.h
index 4850436..0a1dfd0 100644
--- a/mm-video-v4l2/vidc/venc/inc/video_encoder_device_v4l2.h
+++ b/mm-video-v4l2/vidc/venc/inc/video_encoder_device_v4l2.h
@@ -531,6 +531,7 @@
         unsigned long venc_get_codectype(OMX_VIDEO_CODINGTYPE eCompressionFormat);
         bool venc_set_nal_size (OMX_VIDEO_CONFIG_NALSIZE *nalSizeInfo);
         bool venc_set_grid_enable();
+        bool venc_set_extradata_hdr10metadata();
 
         OMX_U32 pmem_free();
         OMX_U32 pmem_allocate(OMX_U32 size, OMX_U32 alignment, OMX_U32 count);
@@ -550,6 +551,8 @@
         bool extradata;
         struct extradata_buffer_info input_extradata_info;
         struct extradata_buffer_info output_extradata_info;
+        bool m_hdr10meta_enabled;
+        ColorMetaData colorData= {};
 
         pthread_mutex_t pause_resume_mlock;
         pthread_cond_t pause_resume_cond;
diff --git a/mm-video-v4l2/vidc/venc/src/video_encoder_device_v4l2.cpp b/mm-video-v4l2/vidc/venc/src/video_encoder_device_v4l2.cpp
index 1f1d45e..73601b8 100644
--- a/mm-video-v4l2/vidc/venc/src/video_encoder_device_v4l2.cpp
+++ b/mm-video-v4l2/vidc/venc/src/video_encoder_device_v4l2.cpp
@@ -637,6 +637,8 @@
     OMX_OTHER_EXTRADATATYPE *data = NULL;
     struct roidata roi;
     bool status = true;
+    OMX_U32 packet_size = 0;
+    OMX_U32 payload_size = 0;
 
     if (!EXTRADATA_IDX(num_input_planes)) {
         DEBUG_PRINT_LOW("Input extradata not enabled");
@@ -774,9 +776,9 @@
         data->nDataSize = ALIGN(sizeof(struct msm_vidc_roi_deltaqp_payload),256)
                             + numBytesAligned;
         data->nSize = ALIGN(sizeof(OMX_OTHER_EXTRADATATYPE) + data->nDataSize, 4);
-        if (data->nSize > input_extradata_info.buffer_size  - consumed_len) {
+        if (data->nSize > input_extradata_info.buffer_size  - filled_len) {
            DEBUG_PRINT_ERROR("Buffer size (%lu) is less than ROI extradata size (%u)",
-                             (input_extradata_info.buffer_size - consumed_len) ,data->nSize);
+                             (input_extradata_info.buffer_size - filled_len) ,data->nSize);
            status = false;
            goto bailout;
         }
@@ -822,8 +824,8 @@
                 *pBuf++ = (1 << 11) | ((clientROI & 0x3F)<< 4);
             }
         }
+        filled_len += data->nSize;
         data = (OMX_OTHER_EXTRADATATYPE *)((char *)data + data->nSize);
-        consumed_len += data->nSize;
     }
 
     if (m_roi_enabled) {
@@ -833,6 +835,33 @@
         }
     }
 
+    /* HDR10Plus MetaData information. Enabled by Default. */
+    payload_size = sizeof(struct msm_vidc_hdr10plus_metadata_payload) - sizeof(unsigned int)
+                                + colorData.dynamicMetaDataLen;
+    packet_size = (sizeof(OMX_OTHER_EXTRADATATYPE) + payload_size + 3)&(~3);
+
+    if (m_hdr10meta_enabled && (filled_len + packet_size <= input_extradata_info.buffer_size)) {
+        struct msm_vidc_hdr10plus_metadata_payload *payload;
+
+        data->nSize = packet_size;
+        data->nVersion.nVersion = OMX_SPEC_VERSION;
+        data->nPortIndex = 0;
+        data->eType = (OMX_EXTRADATATYPE)MSM_VIDC_EXTRADATA_HDR10PLUS_METADATA;
+        data->nDataSize = payload_size;
+
+        payload = (struct  msm_vidc_hdr10plus_metadata_payload *)(data->data);
+        payload->size = colorData.dynamicMetaDataLen;
+        memcpy(payload->data, colorData.dynamicMetaDataPayload, colorData.dynamicMetaDataLen);
+
+        filled_len += data->nSize;
+        data = (OMX_OTHER_EXTRADATATYPE *)((char *)data + data->nSize);
+    } else {
+        if (m_hdr10meta_enabled) {
+            DEBUG_PRINT_HIGH("Insufficient size for HDR10Metadata: Required %u Available %lu",
+                             packet_size, (input_extradata_info.buffer_size - filled_len));
+        }
+    }
+
 #ifdef _VQZIP_
     if (vqzip_sei_info.enabled && !input_extradata_info.vqzip_sei_found) {
         DEBUG_PRINT_ERROR("VQZIP is enabled, But no VQZIP SEI found. Rejecting the session");
@@ -3539,6 +3568,28 @@
 
     return true;
 }
+bool venc_dev::venc_set_extradata_hdr10metadata()
+{
+    struct v4l2_control control;
+
+    if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_HEVC &&
+        codec_profile.profile == V4L2_MPEG_VIDC_VIDEO_HEVC_PROFILE_MAIN10) {
+
+        control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
+        control.value = V4L2_MPEG_VIDC_EXTRADATA_HDR10PLUS_METADATA;
+
+        DEBUG_PRINT_HIGH("venc_set_extradata:: HDR10PLUS_METADATA");
+
+        if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
+            DEBUG_PRINT_ERROR("ERROR: Set extradata HDR10PLUS_METADATA failed %d", errno);
+            return false;
+        }
+        m_hdr10meta_enabled = true;
+        extradata = true;
+    }
+
+    return true;
+}
 
 unsigned venc_dev::venc_start(void)
 {
@@ -3587,6 +3638,8 @@
         return 1;
     }
 
+    //venc_set_extradata_hdr10metadata();
+
     venc_config_print();
 
     /* set buffercount before start */
@@ -4141,9 +4194,11 @@
                         // Moment of truth... actual colorspace is known here..
                         if (getMetaData(handle, GET_COLOR_METADATA, &colorData) == 0) {
                             DEBUG_PRINT_INFO("ENC_CONFIG: gralloc Color MetaData colorPrimaries=%d colorRange=%d "
-                                             "transfer=%d matrixcoefficients=%d",
+                                             "transfer=%d matrixcoefficients=%d"
+                                             "dynamicMetaDataValid %u dynamicMetaDataLen %u",
                                              colorData.colorPrimaries, colorData.range,
-                                             colorData.transfer, colorData.matrixCoefficients);
+                                             colorData.transfer, colorData.matrixCoefficients,
+                                             colorData.dynamicMetaDataValid, colorData.dynamicMetaDataLen);
                         }
 
                         struct v4l2_format fmt;
@@ -4263,7 +4318,14 @@
                             DEBUG_PRINT_ERROR("VIDIOC_REQBUFS OUTPUT_MPLANE Failed");
                             return false;
                         }
-                    }
+                    } else {
+                        if (m_hdr10meta_enabled) {
+                            if (getMetaData(handle, GET_COLOR_METADATA, &colorData) == 0) {
+                                DEBUG_PRINT_INFO("ENC_CONFIG: gralloc Color MetaData dynamicMetaDataValid=%u dynamicMetaDataLen=%u",
+                                                 colorData.dynamicMetaDataValid, colorData.dynamicMetaDataLen);
+                            }
+                        }
+                    } // Check OUTPUT Streaming
 
 
                     uint32_t encodePerfMode = 0;