Pārlūkot izejas kodu

video: driver: add support to configure colorinfo via control

- introduce control to set colorspace. client will use this
  to set private color info.

Change-Id: I0099ef1525f4562d3be3a6e518d046fe5b9ef894
Signed-off-by: Darshana Patil <[email protected]>
Darshana Patil 2 gadi atpakaļ
vecāks
revīzija
ed80204a9e

+ 11 - 0
driver/platform/kalama/src/msm_vidc_kalama.c

@@ -1935,6 +1935,12 @@ static struct msm_platform_inst_capability instance_cap_data_kalama[] = {
 		V4L2_CID_MPEG_VIDC_H264_ENCODE_DELIVERY_MODE,
 		HFI_PROP_ENABLE_SLICE_DELIVERY,
 		CAP_FLAG_OUTPUT_PORT},
+
+	{SIGNAL_COLOR_INFO, ENC, CODECS_ALL,
+		0, INT_MAX, 1, 0,
+		V4L2_CID_MPEG_VIDC_SIGNAL_COLOR_INFO,
+		HFI_PROP_SIGNAL_COLOR_INFO,
+		CAP_FLAG_INPUT_PORT | CAP_FLAG_DYNAMIC_ALLOWED},
 };
 
 static struct msm_platform_inst_cap_dependency instance_cap_dependency_data_kalama[] = {
@@ -2474,6 +2480,11 @@ static struct msm_platform_inst_cap_dependency instance_cap_dependency_data_kala
 		{0},
 		NULL,
 		msm_vidc_set_vui_timing_info},
+
+	{SIGNAL_COLOR_INFO, ENC, CODECS_ALL,
+		{0},
+		NULL,
+		msm_vidc_set_signal_color_info},
 };
 
 /* Default UBWC config for LPDDR5 */

+ 11 - 0
driver/platform/pineapple/src/msm_vidc_pineapple.c

@@ -1943,6 +1943,12 @@ static struct msm_platform_inst_capability instance_cap_data_pineapple[] = {
 		V4L2_CID_MPEG_VIDC_H264_ENCODE_DELIVERY_MODE,
 		HFI_PROP_ENABLE_SLICE_DELIVERY,
 		CAP_FLAG_OUTPUT_PORT},
+
+	{SIGNAL_COLOR_INFO, ENC, CODECS_ALL,
+		0, INT_MAX, 1, 0,
+		V4L2_CID_MPEG_VIDC_SIGNAL_COLOR_INFO,
+		HFI_PROP_SIGNAL_COLOR_INFO,
+		CAP_FLAG_INPUT_PORT | CAP_FLAG_DYNAMIC_ALLOWED},
 };
 
 static struct msm_platform_inst_cap_dependency instance_cap_dependency_data_pineapple[] = {
@@ -2507,6 +2513,11 @@ static struct msm_platform_inst_cap_dependency instance_cap_dependency_data_pine
 		{0},
 		NULL,
 		msm_vidc_set_vui_timing_info},
+
+	{SIGNAL_COLOR_INFO, ENC, CODECS_ALL,
+		{0},
+		NULL,
+		msm_vidc_set_signal_color_info},
 };
 
 /* Default UBWC config for LPDDR5 */

+ 2 - 0
driver/vidc/inc/msm_vidc_control_ext.h

@@ -14,5 +14,7 @@ int msm_vidc_adjust_dec_operating_rate(void *instance, struct v4l2_ctrl *ctrl);
 int msm_vidc_adjust_delivery_mode(void *instance, struct v4l2_ctrl *ctrl);
 int msm_vidc_set_ir_period(void *instance,
 	enum msm_vidc_inst_capability_type cap_id);
+int msm_vidc_set_signal_color_info(void *instance,
+	enum msm_vidc_inst_capability_type cap_id);
 
 #endif

+ 1 - 0
driver/vidc/inc/msm_vidc_internal.h

@@ -367,6 +367,7 @@ enum msm_vidc_metadata_bits {
 	CAP(LOWLATENCY_MAX_BITRATE)               \
 	CAP(LAST_FLAG_EVENT_ENABLE)               \
 	CAP(NUM_COMV)                             \
+	CAP(SIGNAL_COLOR_INFO)                    \
 	CAP(INST_CAP_MAX)                         \
 }
 

+ 5 - 0
driver/vidc/src/msm_venc.c

@@ -323,6 +323,11 @@ static int msm_venc_set_colorspace(struct msm_vidc_inst* inst,
 		return -EINVAL;
 	}
 
+	if (inst->capabilities->cap[SIGNAL_COLOR_INFO].flags & CAP_FLAG_CLIENT_SET) {
+		i_vpr_h(inst, "%s: client configured colorspace via control\n", __func__);
+		return 0;
+	}
+
 	input_fmt = &inst->fmts[INPUT_PORT];
 	pix_fmt = v4l2_colorformat_to_driver(inst,
 		input_fmt->fmt.pix_mp.pixelformat, __func__);

+ 76 - 0
driver/vidc/src/msm_vidc_control_ext.c

@@ -201,3 +201,79 @@ int msm_vidc_set_ir_period(void *instance,
 	return rc;
 }
 
+int msm_vidc_set_signal_color_info(void *instance,
+	enum msm_vidc_inst_capability_type cap_id)
+{
+	int rc = 0;
+	struct msm_vidc_inst *inst = (struct msm_vidc_inst *)instance;
+	struct msm_vidc_inst_capability *capability;
+	u32 color_info, matrix_coeff, transfer_char, primaries, range;
+	u32 full_range = 0;
+	u32 colour_description_present_flag = 0;
+	u32 video_signal_type_present_flag = 0, hfi_value = 0;
+	struct v4l2_format *input_fmt;
+	u32 pix_fmt;
+	/* Unspecified video format */
+	u32 video_format = 5;
+
+	if (!inst || !inst->capabilities) {
+		d_vpr_e("%s: invalid params\n", __func__);
+		return -EINVAL;
+	}
+	capability = inst->capabilities;
+
+	if (!(capability->cap[cap_id].flags & CAP_FLAG_CLIENT_SET)) {
+		i_vpr_h(inst, "%s: colorspace not configured via control\n", __func__);
+		return 0;
+	}
+
+	color_info = capability->cap[cap_id].value;
+	matrix_coeff = color_info & 0xFF;
+	transfer_char = (color_info & 0xFF00) >> 8;
+	primaries = (color_info & 0xFF0000) >> 16;
+	range = (color_info & 0xFF000000) >> 24;
+
+	input_fmt = &inst->fmts[INPUT_PORT];
+	pix_fmt = v4l2_colorformat_to_driver(inst,
+		input_fmt->fmt.pix_mp.pixelformat, __func__);
+	if (primaries != V4L2_COLORSPACE_DEFAULT ||
+	    matrix_coeff != V4L2_YCBCR_ENC_DEFAULT ||
+	    transfer_char != V4L2_XFER_FUNC_DEFAULT) {
+		colour_description_present_flag = 1;
+		video_signal_type_present_flag = 1;
+		primaries = v4l2_color_primaries_to_driver(inst,
+			primaries, __func__);
+		matrix_coeff = v4l2_matrix_coeff_to_driver(inst,
+			matrix_coeff, __func__);
+		transfer_char = v4l2_transfer_char_to_driver(inst,
+			transfer_char, __func__);
+	} else if (is_rgba_colorformat(pix_fmt)) {
+		colour_description_present_flag = 1;
+		video_signal_type_present_flag = 1;
+		primaries = MSM_VIDC_PRIMARIES_BT709;
+		matrix_coeff = MSM_VIDC_MATRIX_COEFF_BT709;
+		transfer_char = MSM_VIDC_TRANSFER_BT709;
+		full_range = 0;
+	}
+
+	if (range != V4L2_QUANTIZATION_DEFAULT) {
+		video_signal_type_present_flag = 1;
+		full_range = range == V4L2_QUANTIZATION_FULL_RANGE ? 1 : 0;
+	}
+
+	hfi_value = (matrix_coeff & 0xFF) |
+		((transfer_char << 8) & 0xFF00) |
+		((primaries << 16) & 0xFF0000) |
+		((colour_description_present_flag << 24) & 0x1000000) |
+		((full_range << 25) & 0x2000000) |
+		((video_format << 26) & 0x1C000000) |
+		((video_signal_type_present_flag << 29) & 0x20000000);
+
+	rc = msm_vidc_packetize_control(inst, cap_id, HFI_PAYLOAD_32_PACKED,
+		&hfi_value, sizeof(u32), __func__);
+	if (rc)
+		return rc;
+
+	return rc;
+}
+

+ 30 - 0
include/uapi/vidc/media/v4l2_vidc_extensions.h

@@ -30,10 +30,20 @@
 /* AV1 */
 #define V4L2_PIX_FMT_AV1                        v4l2_fourcc('A', 'V', '1', '0')
 /* start of vidc specific colorspace definitions */
+/*
+ * V4L2_COLORSPACE_VIDC_START, V4L2_XFER_FUNC_VIDC_START
+ * and V4L2_YCBCR_VIDC_START are introduced because
+ * V4L2_COLORSPACE_LAST, V4L2_XFER_FUNC_LAST, and
+ * V4L2_YCBCR_ENC_LAST respectively are not accessible
+ * in userspace. These values are needed in userspace
+ * to check if the colorspace info is private.
+ */
+#define V4L2_COLORSPACE_VIDC_START           100
 #define V4L2_COLORSPACE_VIDC_GENERIC_FILM    101
 #define V4L2_COLORSPACE_VIDC_EG431           102
 #define V4L2_COLORSPACE_VIDC_EBU_TECH        103
 
+#define V4L2_XFER_FUNC_VIDC_START            200
 #define V4L2_XFER_FUNC_VIDC_BT470_SYSTEM_M   201
 #define V4L2_XFER_FUNC_VIDC_BT470_SYSTEM_BG  202
 #define V4L2_XFER_FUNC_VIDC_BT601_525_OR_625 203
@@ -45,6 +55,7 @@
 #define V4L2_XFER_FUNC_VIDC_HLG              209
 
 /* should be 255 or below due to u8 limitation */
+#define V4L2_YCBCR_VIDC_START                240
 #define V4L2_YCBCR_VIDC_SRGB_OR_SMPTE_ST428  241
 #define V4L2_YCBCR_VIDC_FCC47_73_682         242
 
@@ -268,6 +279,25 @@ enum v4l2_mpeg_video_av1_tier {
 #define V4L2_CID_MPEG_VIDC_EARLY_NOTIFY_LINE_COUNT                            \
 	(V4L2_CID_MPEG_VIDC_BASE + 0x45)
 
+/*
+ * This control is introduced to overcome v4l2 limitation
+ * of allowing only standard colorspace info via s_fmt.
+ * v4l_sanitize_colorspace() is introduced in s_fmt ioctl
+ * to reject private colorspace. Through this control, client
+ * can set private colorspace info and/or use this control
+ * to set colorspace dynamically.
+ * The control value is 32 bits packed as:
+ *      [ 0 -  7] : matrix coefficients
+ *      [ 8 - 15] : transfer characteristics
+ *      [16 - 23] : colour primaries
+ *      [24 - 31] : range
+ * This control is only for encoder.
+ * Currently g_fmt in v4l2 does not santize colorspace,
+ * hence this control is not introduced for decoder.
+ */
+#define V4L2_CID_MPEG_VIDC_SIGNAL_COLOR_INFO                                  \
+	(V4L2_CID_MPEG_VIDC_BASE + 0x46)
+
 /* add new controls above this line */
 /* Deprecate below controls once availble in gki and gsi bionic header */
 #ifndef V4L2_CID_MPEG_VIDEO_BASELAYER_PRIORITY_ID