msm: vidc: HDR10 PQ SEI generation for HEVC encoder

To enable HDR10 PQ feature, the userspace sets controls
for content light level and mastering display info. A
single property is set for both the controls to video
hardware so as to generate the SEI in encoded bitstream.
Use s64 datatype for minimum, maximum and default control
value to support UINT_MAX.

CRs-Fixed: 2100854
Change-Id: I42f8b11c5d3ccf0457d8088b2bdb30de3744e211
Signed-off-by: Umesh Pandey <umeshp@codeaurora.org>
diff --git a/drivers/media/platform/msm/vidc/hfi_packetization.c b/drivers/media/platform/msm/vidc/hfi_packetization.c
index cf0413e..89e83b8 100644
--- a/drivers/media/platform/msm/vidc/hfi_packetization.c
+++ b/drivers/media/platform/msm/vidc/hfi_packetization.c
@@ -1877,6 +1877,22 @@
 		pkt->size += sizeof(u32) + sizeof(*work_mode);
 		break;
 	}
+	case HAL_PARAM_VENC_HDR10_PQ_SEI:
+	{
+		struct hfi_hdr10_pq_sei *hfi;
+		struct hal_hdr10_pq_sei *prop =
+			(struct hal_hdr10_pq_sei *) pdata;
+
+		pkt->rg_property_data[0] =
+			HFI_PROPERTY_PARAM_VENC_HDR10_PQ_SEI;
+		hfi = (struct hfi_hdr10_pq_sei *)
+			&pkt->rg_property_data[1];
+
+		memcpy(hfi, prop, sizeof(*hfi));
+		pkt->size += sizeof(u32) +
+			sizeof(struct hfi_hdr10_pq_sei);
+		break;
+	}
 	/* FOLLOWING PROPERTIES ARE NOT IMPLEMENTED IN CORE YET */
 	case HAL_CONFIG_BUFFER_REQUIREMENTS:
 	case HAL_CONFIG_PRIORITY:
diff --git a/drivers/media/platform/msm/vidc/msm_venc.c b/drivers/media/platform/msm/vidc/msm_venc.c
index 266c50e..85b4724 100644
--- a/drivers/media/platform/msm/vidc/msm_venc.c
+++ b/drivers/media/platform/msm/vidc/msm_venc.c
@@ -1068,6 +1068,135 @@
 		),
 		.qmenu = mpeg_video_flip,
 	},
+	{
+		.id = V4L2_CID_MPEG_VIDC_VENC_HDR_INFO,
+		.name = "Enable/Disable HDR INFO",
+		.type = V4L2_CTRL_TYPE_BOOLEAN,
+		.minimum = V4L2_MPEG_VIDC_VENC_HDR_INFO_DISABLED,
+		.maximum = V4L2_MPEG_VIDC_VENC_HDR_INFO_ENABLED,
+		.default_value = V4L2_MPEG_VIDC_VENC_HDR_INFO_DISABLED,
+		.step = 1,
+	},
+	{
+		.id = V4L2_CID_MPEG_VIDC_VENC_RGB_PRIMARY_00,
+		.name = "RGB PRIMARIES[0][0]",
+		.type = V4L2_CTRL_TYPE_U32,
+		.minimum = 0,
+		.maximum = UINT_MAX,
+		.default_value = 0,
+		.step = 1,
+		.qmenu = NULL,
+	},
+	{
+		.id = V4L2_CID_MPEG_VIDC_VENC_RGB_PRIMARY_01,
+		.name = "RGB PRIMARIES[0][1]",
+		.type = V4L2_CTRL_TYPE_U32,
+		.minimum = 0,
+		.maximum = UINT_MAX,
+		.default_value = 0,
+		.step = 1,
+		.qmenu = NULL,
+	},
+	{
+		.id = V4L2_CID_MPEG_VIDC_VENC_RGB_PRIMARY_10,
+		.name = "RGB PRIMARIES[1][0]",
+		.type = V4L2_CTRL_TYPE_U32,
+		.minimum = 0,
+		.maximum = UINT_MAX,
+		.default_value = 0,
+		.step = 1,
+		.qmenu = NULL,
+	},
+	{
+		.id = V4L2_CID_MPEG_VIDC_VENC_RGB_PRIMARY_11,
+		.name = "RGB PRIMARIES[1][1]",
+		.type = V4L2_CTRL_TYPE_U32,
+		.minimum = 0,
+		.maximum = UINT_MAX,
+		.default_value = 0,
+		.step = 1,
+		.qmenu = NULL,
+	},
+	{
+		.id = V4L2_CID_MPEG_VIDC_VENC_RGB_PRIMARY_20,
+		.name = "RGB PRIMARIES[2][0]",
+		.type = V4L2_CTRL_TYPE_U32,
+		.minimum = 0,
+		.maximum = UINT_MAX,
+		.default_value = 0,
+		.step = 1,
+		.qmenu = NULL,
+	},
+	{
+		.id = V4L2_CID_MPEG_VIDC_VENC_RGB_PRIMARY_21,
+		.name = "RGB PRIMARIES[2][1]",
+		.type = V4L2_CTRL_TYPE_U32,
+		.minimum = 0,
+		.maximum = UINT_MAX,
+		.default_value = 0,
+		.step = 1,
+		.qmenu = NULL,
+	},
+	{
+		.id = V4L2_CID_MPEG_VIDC_VENC_WHITEPOINT_X,
+		.name = "WHITE POINT X",
+		.type = V4L2_CTRL_TYPE_U32,
+		.minimum = 0,
+		.maximum = UINT_MAX,
+		.default_value = 0,
+		.step = 1,
+		.qmenu = NULL,
+	},
+	{
+		.id = V4L2_CID_MPEG_VIDC_VENC_WHITEPOINT_Y,
+		.name = "WHITE POINT Y",
+		.type = V4L2_CTRL_TYPE_U32,
+		.minimum = 0,
+		.maximum = UINT_MAX,
+		.default_value = 0,
+		.step = 1,
+		.qmenu = NULL,
+	},
+	{
+		.id = V4L2_CID_MPEG_VIDC_VENC_MAX_DISP_LUM,
+		.name = "MAX DISPLAY LUMINANCE",
+		.type =  V4L2_CTRL_TYPE_U32,
+		.minimum = 0,
+		.maximum = UINT_MAX,
+		.default_value = 0,
+		.step = 1,
+		.qmenu = NULL,
+	},
+	{
+		.id = V4L2_CID_MPEG_VIDC_VENC_MIN_DISP_LUM,
+		.name = "MIN DISPLAY LUMINANCE",
+		.type = V4L2_CTRL_TYPE_U32,
+		.minimum = 0,
+		.maximum = UINT_MAX,
+		.default_value = 0,
+		.step = 1,
+		.qmenu = NULL,
+	},
+	{
+		.id = V4L2_CID_MPEG_VIDC_VENC_MAX_CLL,
+		.name = "MAX CLL",
+		.type = V4L2_CTRL_TYPE_U32,
+		.minimum = 0,
+		.maximum = UINT_MAX,
+		.default_value = 0,
+		.step = 1,
+		.qmenu = NULL,
+	},
+	{
+		.id = V4L2_CID_MPEG_VIDC_VENC_MAX_FLL,
+		.name = "MAX FLL",
+		.type = V4L2_CTRL_TYPE_U32,
+		.minimum = 0,
+		.maximum = UINT_MAX,
+		.default_value = 0,
+		.step = 1,
+		.qmenu = NULL,
+	},
 
 };
 
@@ -2095,6 +2224,19 @@
 	case V4L2_CID_MPEG_VIDC_VIDEO_I_FRAME_QP_MAX:
 	case V4L2_CID_MPEG_VIDC_VIDEO_P_FRAME_QP_MAX:
 	case V4L2_CID_MPEG_VIDC_VIDEO_B_FRAME_QP_MAX:
+	case V4L2_CID_MPEG_VIDC_VENC_HDR_INFO:
+	case V4L2_CID_MPEG_VIDC_VENC_RGB_PRIMARY_00:
+	case V4L2_CID_MPEG_VIDC_VENC_RGB_PRIMARY_01:
+	case V4L2_CID_MPEG_VIDC_VENC_RGB_PRIMARY_10:
+	case V4L2_CID_MPEG_VIDC_VENC_RGB_PRIMARY_11:
+	case V4L2_CID_MPEG_VIDC_VENC_RGB_PRIMARY_20:
+	case V4L2_CID_MPEG_VIDC_VENC_RGB_PRIMARY_21:
+	case V4L2_CID_MPEG_VIDC_VENC_WHITEPOINT_X:
+	case V4L2_CID_MPEG_VIDC_VENC_WHITEPOINT_Y:
+	case V4L2_CID_MPEG_VIDC_VENC_MAX_DISP_LUM:
+	case V4L2_CID_MPEG_VIDC_VENC_MIN_DISP_LUM:
+	case V4L2_CID_MPEG_VIDC_VENC_MAX_CLL:
+	case V4L2_CID_MPEG_VIDC_VENC_MAX_FLL:
 		dprintk(VIDC_DBG, "Set the control : %#x using ext ctrl\n",
 			ctrl->id);
 		break;
@@ -2133,6 +2275,11 @@
 	struct hal_frame_size blur_res;
 	struct hal_quantization_range qp_range;
 	struct hal_quantization qp;
+	struct hal_hdr10_pq_sei hdr10_sei_params;
+	struct msm_vidc_mastering_display_colour_sei_payload *mdisp_sei
+		= &(hdr10_sei_params.disp_color_sei);
+	struct msm_vidc_content_light_level_sei_payload *cll_sei
+		= &(hdr10_sei_params.cll_sei);
 
 	if (!inst || !inst->core || !inst->core->device || !ctrl) {
 		dprintk(VIDC_ERR, "%s invalid parameters\n", __func__);
@@ -2281,6 +2428,75 @@
 			i++;
 			}
 			break;
+		case V4L2_CID_MPEG_VIDC_VENC_HDR_INFO:
+			if (control[i].value ==
+				V4L2_MPEG_VIDC_VENC_HDR_INFO_DISABLED)
+				break;
+			memset(&hdr10_sei_params, 0, sizeof(hdr10_sei_params));
+			i++;
+			while (i < ctrl->count) {
+				switch (control[i].id) {
+				case V4L2_CID_MPEG_VIDC_VENC_RGB_PRIMARY_00:
+					mdisp_sei->nDisplayPrimariesX[0] =
+						control[i].value;
+					break;
+				case V4L2_CID_MPEG_VIDC_VENC_RGB_PRIMARY_01:
+					mdisp_sei->nDisplayPrimariesY[0] =
+						control[i].value;
+					break;
+				case V4L2_CID_MPEG_VIDC_VENC_RGB_PRIMARY_10:
+					mdisp_sei->nDisplayPrimariesX[1] =
+						control[i].value;
+					break;
+				case V4L2_CID_MPEG_VIDC_VENC_RGB_PRIMARY_11:
+					mdisp_sei->nDisplayPrimariesY[1] =
+						control[i].value;
+					break;
+				case V4L2_CID_MPEG_VIDC_VENC_RGB_PRIMARY_20:
+					mdisp_sei->nDisplayPrimariesX[2] =
+						control[i].value;
+					break;
+				case V4L2_CID_MPEG_VIDC_VENC_RGB_PRIMARY_21:
+					mdisp_sei->nDisplayPrimariesY[2] =
+						control[i].value;
+					break;
+				case V4L2_CID_MPEG_VIDC_VENC_WHITEPOINT_X:
+					mdisp_sei->nWhitePointX =
+						control[i].value;
+					break;
+				case V4L2_CID_MPEG_VIDC_VENC_WHITEPOINT_Y:
+					mdisp_sei->nWhitePointY =
+						control[i].value;
+					break;
+				case V4L2_CID_MPEG_VIDC_VENC_MAX_DISP_LUM:
+					mdisp_sei->
+						nMaxDisplayMasteringLuminance =
+						control[i].value;
+					break;
+				case V4L2_CID_MPEG_VIDC_VENC_MIN_DISP_LUM:
+					mdisp_sei->
+						nMinDisplayMasteringLuminance =
+						control[i].value;
+					break;
+				case V4L2_CID_MPEG_VIDC_VENC_MAX_CLL:
+					cll_sei->nMaxContentLight =
+						control[i].value;
+					break;
+				case V4L2_CID_MPEG_VIDC_VENC_MAX_FLL:
+					cll_sei->nMaxPicAverageLight =
+						control[i].value;
+					break;
+				default:
+					dprintk(VIDC_ERR,
+							"Unknown Ctrl:%d, not part of HDR Info",
+							control[i].id);
+				}
+				i++;
+			}
+			property_id =
+				HAL_PARAM_VENC_HDR10_PQ_SEI;
+			pdata = &hdr10_sei_params;
+			break;
 		default:
 			dprintk(VIDC_ERR, "Invalid id set: %d\n",
 				control[i].id);
diff --git a/drivers/media/platform/msm/vidc/msm_vidc_internal.h b/drivers/media/platform/msm/vidc/msm_vidc_internal.h
index 37645fe..d540992 100644
--- a/drivers/media/platform/msm/vidc/msm_vidc_internal.h
+++ b/drivers/media/platform/msm/vidc/msm_vidc_internal.h
@@ -422,9 +422,9 @@
 	u32 id;
 	char name[MAX_NAME_LENGTH];
 	enum v4l2_ctrl_type type;
-	s32 minimum;
-	s32 maximum;
-	s32 default_value;
+	s64 minimum;
+	s64 maximum;
+	s64 default_value;
 	u32 step;
 	u32 menu_skip_mask;
 	u32 flags;
diff --git a/drivers/media/platform/msm/vidc/vidc_hfi_api.h b/drivers/media/platform/msm/vidc/vidc_hfi_api.h
index 53df90f5..2260b55 100644
--- a/drivers/media/platform/msm/vidc/vidc_hfi_api.h
+++ b/drivers/media/platform/msm/vidc/vidc_hfi_api.h
@@ -226,6 +226,7 @@
 	HAL_PARAM_VIDEO_CORES_USAGE,
 	HAL_PARAM_VIDEO_WORK_MODE,
 	HAL_PARAM_SECURE,
+	HAL_PARAM_VENC_HDR10_PQ_SEI,
 };
 
 enum hal_domain {
@@ -1398,6 +1399,11 @@
 	u32 rg_property_data[1];
 };
 
+struct hal_hdr10_pq_sei {
+	struct msm_vidc_mastering_display_colour_sei_payload disp_color_sei;
+	struct msm_vidc_content_light_level_sei_payload cll_sei;
+};
+
 #define call_hfi_op(q, op, args...)			\
 	(((q) && (q)->op) ? ((q)->op(args)) : 0)
 
diff --git a/drivers/media/platform/msm/vidc/vidc_hfi_helper.h b/drivers/media/platform/msm/vidc/vidc_hfi_helper.h
index 001ca39..ca6d803 100644
--- a/drivers/media/platform/msm/vidc/vidc_hfi_helper.h
+++ b/drivers/media/platform/msm/vidc/vidc_hfi_helper.h
@@ -321,6 +321,10 @@
 	(HFI_PROPERTY_PARAM_VENC_COMMON_START + 0x033)
 #define  HFI_PROPERTY_PARAM_VENC_IFRAMESIZE			\
 	(HFI_PROPERTY_PARAM_VENC_COMMON_START + 0x034)
+#define  HFI_PROPERTY_PARAM_VENC_SEND_OUTPUT_FOR_SKIPPED_FRAMES	\
+	(HFI_PROPERTY_PARAM_VENC_COMMON_START + 0x035)
+#define  HFI_PROPERTY_PARAM_VENC_HDR10_PQ_SEI			\
+	(HFI_PROPERTY_PARAM_VENC_COMMON_START + 0x036)
 
 #define HFI_PROPERTY_CONFIG_VENC_COMMON_START				\
 	(HFI_DOMAIN_BASE_VENC + HFI_ARCH_COMMON_OFFSET + 0x6000)
@@ -1058,4 +1062,24 @@
 	u32 packet_type;
 	u32 trigger_type;
 };
+
+struct hfi_mastering_display_colour_sei_payload {
+	u32 display_primariesX[3];
+	u32 display_primariesY[3];
+	u32 white_pointX;
+	u32 white_pointY;
+	u32 max_display_mastering_luminance;
+	u32 min_display_mastering_luminance;
+};
+
+struct hfi_content_light_level_sei_payload {
+	u32 max_content_light;
+	u32 max_pic_average_light;
+};
+
+struct hfi_hdr10_pq_sei {
+	struct hfi_mastering_display_colour_sei_payload mdisp_info;
+	struct hfi_content_light_level_sei_payload cll_info;
+};
+
 #endif