Forráskód Böngészése

video: driver: enable dynamic metadata

- enable Eva stats, hdr10/10+ as dynamic metadata.
- Make eva stats dependent on bitrate mode.
  Also remove preprocess and layer count as
  child of Eva stats.
- Make Hdr10/10+ dependent on profile.
- Adjust transcoding stats metadata based on
  bitrate mode, fps and resolution.

Change-Id: I7b110962e29db50cb321d69a0fb301950436da6f
Signed-off-by: Darshana Patil <[email protected]>
Darshana Patil 2 éve
szülő
commit
fc6a238b09

+ 5 - 0
driver/platform/common/inc/msm_vidc_platform.h

@@ -330,6 +330,11 @@ int msm_vidc_adjust_all_intra(void *instance, struct v4l2_ctrl *ctrl);
 int msm_vidc_adjust_dec_outbuf_fence(void *instance, struct v4l2_ctrl *ctrl);
 int msm_vidc_adjust_dec_slice_mode(void *instance, struct v4l2_ctrl *ctrl);
 int msm_vidc_adjust_preprocess(void *instance, struct v4l2_ctrl *ctrl);
+int msm_vidc_adjust_eva_stats(void *instance, struct v4l2_ctrl *ctrl);
+int msm_vidc_adjust_sei_mastering_disp(void *instance, struct v4l2_ctrl *ctrl);
+int msm_vidc_adjust_sei_cll(void *instance, struct v4l2_ctrl *ctrl);
+int msm_vidc_adjust_hdr10plus(void *instance, struct v4l2_ctrl *ctrl);
+int msm_vidc_adjust_transcoding_stats(void *instance, struct v4l2_ctrl *ctrl);
 
 int msm_vidc_set_header_mode(void *instance,
 	enum msm_vidc_inst_capability_type cap_id);

+ 213 - 31
driver/platform/common/src/msm_vidc_platform.c

@@ -524,11 +524,19 @@ int msm_vidc_update_cap_value(struct msm_vidc_inst *inst, u32 cap_id,
 	prev_value = inst->capabilities->cap[cap_id].value;
 
 	if (is_meta_cap(inst, cap_id)) {
+		if (adjusted_val & MSM_VIDC_META_ENABLE &&
+			adjusted_val & MSM_VIDC_META_DYN_ENABLE) {
+			i_vpr_e(inst,
+				"%s: %s cannot be enabled both statically and dynamically",
+				__func__, cap_name(cap_id));
+			return -EINVAL;
+		}
 		/*
 		 * cumulative control value if client set same metadata
 		 * control multiple times.
 		 */
-		if (adjusted_val & MSM_VIDC_META_ENABLE) {
+		if (adjusted_val & MSM_VIDC_META_ENABLE ||
+			adjusted_val & MSM_VIDC_META_DYN_ENABLE) {
 			/* enable metadata */
 			inst->capabilities->cap[cap_id].value |= adjusted_val;
 		} else {
@@ -1497,17 +1505,6 @@ static int msm_vidc_adjust_static_layer_count_and_type(struct msm_vidc_inst *ins
 		goto exit;
 	}
 
-	if (hb_requested && layer_count > 1) {
-		if (!is_valid_cap(inst, META_EVA_STATS) ||
-			!is_meta_tx_inp_enabled(inst, META_EVA_STATS)) {
-			i_vpr_h(inst,
-				"%s: only one layer of heirB supported as eva statistics not available\n",
-				__func__);
-			layer_count = 1;
-			goto exit;
-		}
-	}
-
 	/* decide hfi layer type */
 	if (hb_requested) {
 		inst->hfi_layer_type = HFI_HIER_B;
@@ -2414,7 +2411,7 @@ int msm_vidc_adjust_preprocess(void *instance, struct v4l2_ctrl *ctrl)
 {
 	s32 adjusted_value;
 	struct msm_vidc_inst *inst = (struct msm_vidc_inst *) instance;
-	s32 brs = 0, eva_status = -1;
+	s32 brs = 0;
 	u32 width, height, frame_rate, operating_rate, max_fps;
 	struct v4l2_format *f;
 
@@ -2435,22 +2432,8 @@ int msm_vidc_adjust_preprocess(void *instance, struct v4l2_ctrl *ctrl)
 
 	/*
 	 * enable preprocess if
-	 * client did not enable EVA metadata statistics and
 	 * BRS enabled and upto 4k @ 60 fps
 	 */
-	if (is_valid_cap(inst, META_EVA_STATS)) {
-		if (msm_vidc_get_parent_value(inst,
-			REQUEST_PREPROCESS,
-			META_EVA_STATS,
-			&eva_status, __func__))
-			return -EINVAL;
-		/* preprocess not required if client provides eva statistics */
-		if (is_meta_tx_inp_enabled(inst, META_EVA_STATS)) {
-			adjusted_value = 0;
-			goto update_preprocess;
-		}
-	}
-
 	if (is_valid_cap(inst, CONTENT_ADAPTIVE_CODING)) {
 		if (msm_vidc_get_parent_value(inst,
 			REQUEST_PREPROCESS,
@@ -2468,10 +2451,6 @@ int msm_vidc_adjust_preprocess(void *instance, struct v4l2_ctrl *ctrl)
 		goto update_preprocess;
 	}
 
-	/*
-	 * eva statistics not available and BRS enabled, so
-	 * preprocess can be enabled upto 4k @ 60 fps
-	 */
 	if (res_is_less_than_or_equal_to(width, height, 3840, 2160) &&
 		max_fps <= 60)
 		adjusted_value = 1;
@@ -2688,6 +2667,209 @@ int msm_vidc_adjust_dec_slice_mode(void *instance, struct v4l2_ctrl *ctrl)
 	return 0;
 }
 
+int msm_vidc_adjust_eva_stats(void *instance, struct v4l2_ctrl *ctrl)
+{
+	struct msm_vidc_inst_capability *capability;
+	s32 adjusted_value;
+	struct msm_vidc_inst *inst = (struct msm_vidc_inst *) instance;
+	s32 rc_type = -1;
+
+	if (!inst || !inst->capabilities) {
+		d_vpr_e("%s: invalid params\n", __func__);
+		return -EINVAL;
+	}
+	capability = inst->capabilities;
+
+	adjusted_value = ctrl ? ctrl->val : capability->cap[META_EVA_STATS].value;
+
+	if (msm_vidc_get_parent_value(inst, META_EVA_STATS, BITRATE_MODE,
+		&rc_type, __func__))
+		return -EINVAL;
+
+	/* disable Eva stats metadata for CQ rate control */
+	if (rc_type == HFI_RC_CQ) {
+		i_vpr_h(inst, "%s: unsupported for CQ rate control\n", __func__);
+		adjusted_value = 0;
+	}
+
+	msm_vidc_update_cap_value(inst, META_EVA_STATS,
+		adjusted_value, __func__);
+
+	return 0;
+}
+
+int msm_vidc_adjust_sei_mastering_disp(void *instance, struct v4l2_ctrl *ctrl)
+{
+	struct msm_vidc_inst_capability *capability;
+	s32 adjusted_value;
+	struct msm_vidc_inst *inst = (struct msm_vidc_inst *) instance;
+	s32 profile = -1;
+
+	if (!inst || !inst->capabilities) {
+		d_vpr_e("%s: invalid params\n", __func__);
+		return -EINVAL;
+	}
+	capability = inst->capabilities;
+
+	adjusted_value = ctrl ? ctrl->val : capability->cap[META_SEI_MASTERING_DISP].value;
+
+	if (msm_vidc_get_parent_value(inst, META_SEI_MASTERING_DISP, PROFILE,
+		&profile, __func__))
+		return -EINVAL;
+
+	if (inst->codec != MSM_VIDC_HEVC && inst->codec != MSM_VIDC_HEIC) {
+		adjusted_value = 0;
+		goto adjust;
+	}
+
+	if ((inst->codec == MSM_VIDC_HEVC &&
+		profile != V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN_10) ||
+		(inst->codec == MSM_VIDC_HEIC &&
+		profile != V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN_10_STILL_PICTURE)) {
+		adjusted_value = 0;
+		goto adjust;
+	}
+
+adjust:
+	msm_vidc_update_cap_value(inst, META_SEI_MASTERING_DISP,
+		adjusted_value, __func__);
+	return 0;
+}
+
+int msm_vidc_adjust_sei_cll(void *instance, struct v4l2_ctrl *ctrl)
+{
+	struct msm_vidc_inst_capability *capability;
+	s32 adjusted_value;
+	struct msm_vidc_inst *inst = (struct msm_vidc_inst *) instance;
+	s32 profile = -1;
+
+	if (!inst || !inst->capabilities) {
+		d_vpr_e("%s: invalid params\n", __func__);
+		return -EINVAL;
+	}
+	capability = inst->capabilities;
+
+	adjusted_value = ctrl ? ctrl->val : capability->cap[META_SEI_CLL].value;
+
+	if (msm_vidc_get_parent_value(inst, META_SEI_CLL, PROFILE,
+		&profile, __func__))
+		return -EINVAL;
+
+	if (inst->codec != MSM_VIDC_HEVC && inst->codec != MSM_VIDC_HEIC) {
+		adjusted_value = 0;
+		goto adjust;
+	}
+
+	if ((inst->codec == MSM_VIDC_HEVC &&
+		profile != V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN_10) ||
+		(inst->codec == MSM_VIDC_HEIC &&
+		profile != V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN_10_STILL_PICTURE)) {
+		adjusted_value = 0;
+		goto adjust;
+	}
+
+adjust:
+	msm_vidc_update_cap_value(inst, META_SEI_CLL, adjusted_value, __func__);
+	return 0;
+}
+
+int msm_vidc_adjust_hdr10plus(void *instance, struct v4l2_ctrl *ctrl)
+{
+	struct msm_vidc_inst_capability *capability;
+	s32 adjusted_value;
+	struct msm_vidc_inst *inst = (struct msm_vidc_inst *) instance;
+	s32 profile = -1;
+
+	if (!inst || !inst->capabilities) {
+		d_vpr_e("%s: invalid params\n", __func__);
+		return -EINVAL;
+	}
+	capability = inst->capabilities;
+
+	adjusted_value = ctrl ? ctrl->val : capability->cap[META_HDR10PLUS].value;
+
+	if (msm_vidc_get_parent_value(inst, META_HDR10PLUS, PROFILE,
+		&profile, __func__))
+		return -EINVAL;
+
+	if (inst->codec != MSM_VIDC_HEVC && inst->codec != MSM_VIDC_HEIC) {
+		adjusted_value = 0;
+		goto adjust;
+	}
+
+	if ((inst->codec == MSM_VIDC_HEVC &&
+		profile != V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN_10) ||
+		(inst->codec == MSM_VIDC_HEIC &&
+		profile != V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN_10_STILL_PICTURE)) {
+		adjusted_value = 0;
+		goto adjust;
+	}
+
+adjust:
+	msm_vidc_update_cap_value(inst, META_HDR10PLUS, adjusted_value, __func__);
+	return 0;
+}
+
+int msm_vidc_adjust_transcoding_stats(void *instance, struct v4l2_ctrl *ctrl)
+{
+	struct msm_vidc_inst_capability *capability;
+	s32 adjusted_value;
+	struct msm_vidc_inst *inst = (struct msm_vidc_inst *) instance;
+	s32 rc_type = -1;
+	u32 width, height, fps;
+	struct v4l2_format *f;
+
+	if (!inst || !inst->capabilities) {
+		d_vpr_e("%s: invalid params\n", __func__);
+		return -EINVAL;
+	}
+	capability = inst->capabilities;
+
+	adjusted_value = ctrl ? ctrl->val :
+		capability->cap[META_TRANSCODING_STAT_INFO].value;
+
+	if (msm_vidc_get_parent_value(inst, META_TRANSCODING_STAT_INFO,
+		BITRATE_MODE, &rc_type, __func__))
+		return -EINVAL;
+
+	/*
+	 * transcoding stats metadata is supported for:
+	 * - VBR bitrate mode
+	 * - fps <= 60
+	 * - Resolution <= 4K
+	 */
+	if (rc_type != HFI_RC_VBR_CFR) {
+		i_vpr_h(inst, "%s: unsupported rc_type: %#x\n",
+			__func__, rc_type);
+		adjusted_value = 0;
+		goto exit;
+	}
+
+	fps = capability->cap[FRAME_RATE].value >> 16;
+	if (fps > MAX_TRANSCODING_STATS_FRAME_RATE) {
+		i_vpr_h(inst, "%s: unsupported fps %u\n", __func__, fps);
+		adjusted_value = 0;
+		goto exit;
+	}
+
+	f = &inst->fmts[OUTPUT_PORT];
+	width = f->fmt.pix_mp.width;
+	height = f->fmt.pix_mp.height;
+	if (res_is_greater_than(width, height,
+		MAX_TRANSCODING_STATS_WIDTH, MAX_TRANSCODING_STATS_HEIGHT)) {
+		i_vpr_h(inst, "%s: unsupported res, wxh %ux%u\n",
+			__func__, width, height);
+		adjusted_value = 0;
+		goto exit;
+	}
+
+exit:
+	msm_vidc_update_cap_value(inst, META_TRANSCODING_STAT_INFO,
+		adjusted_value, __func__);
+
+	return 0;
+}
+
 /******************* End of Control Adjust functions *************************/
 
 /************************* Control Set functions *****************************/

+ 41 - 13
driver/platform/pineapple/src/msm_vidc_pineapple.c

@@ -1824,7 +1824,8 @@ static struct msm_platform_inst_capability instance_cap_data_pineapple[] = {
 
 	{META_SEI_MASTERING_DISP, ENC, HEVC|HEIC,
 		MSM_VIDC_META_DISABLE,
-		MSM_VIDC_META_ENABLE | MSM_VIDC_META_TX_INPUT,
+		MSM_VIDC_META_ENABLE |
+		MSM_VIDC_META_DYN_ENABLE | MSM_VIDC_META_TX_INPUT,
 		0, MSM_VIDC_META_DISABLE,
 		V4L2_CID_MPEG_VIDC_METADATA_SEI_MASTERING_DISPLAY_COLOUR,
 		HFI_PROP_SEI_MASTERING_DISPLAY_COLOUR,
@@ -1841,7 +1842,8 @@ static struct msm_platform_inst_capability instance_cap_data_pineapple[] = {
 
 	{META_SEI_CLL, ENC, HEVC|HEIC,
 		MSM_VIDC_META_DISABLE,
-		MSM_VIDC_META_ENABLE | MSM_VIDC_META_TX_INPUT,
+		MSM_VIDC_META_ENABLE |
+		MSM_VIDC_META_DYN_ENABLE | MSM_VIDC_META_TX_INPUT,
 		0, MSM_VIDC_META_DISABLE,
 		V4L2_CID_MPEG_VIDC_METADATA_SEI_CONTENT_LIGHT_LEVEL,
 		HFI_PROP_SEI_CONTENT_LIGHT_LEVEL,
@@ -1858,7 +1860,8 @@ static struct msm_platform_inst_capability instance_cap_data_pineapple[] = {
 
 	{META_HDR10PLUS, ENC, HEVC|HEIC,
 		MSM_VIDC_META_DISABLE,
-		MSM_VIDC_META_ENABLE | MSM_VIDC_META_TX_INPUT,
+		MSM_VIDC_META_ENABLE |
+		MSM_VIDC_META_DYN_ENABLE | MSM_VIDC_META_TX_INPUT,
 		0, MSM_VIDC_META_DISABLE,
 		V4L2_CID_MPEG_VIDC_METADATA_HDR10PLUS,
 		HFI_PROP_SEI_HDR10PLUS_USERDATA,
@@ -1889,9 +1892,10 @@ static struct msm_platform_inst_capability instance_cap_data_pineapple[] = {
 		HFI_PROP_DOLBY_RPU_METADATA,
 		CAP_FLAG_BITMASK | CAP_FLAG_META},
 
-	{META_EVA_STATS, ENC, CODECS_ALL,
+	{META_EVA_STATS, ENC, H264|HEVC,
 		MSM_VIDC_META_DISABLE,
-		MSM_VIDC_META_ENABLE | MSM_VIDC_META_TX_INPUT,
+		MSM_VIDC_META_ENABLE |
+		MSM_VIDC_META_DYN_ENABLE | MSM_VIDC_META_TX_INPUT,
 		0, MSM_VIDC_META_DISABLE,
 		V4L2_CID_MPEG_VIDC_METADATA_EVA_STATS,
 		HFI_PROP_EVA_STAT_INFO,
@@ -2120,7 +2124,7 @@ static struct msm_platform_inst_cap_dependency instance_cap_dependency_data_pine
 			P_FRAME_QP, B_FRAME_QP, ENH_LAYER_COUNT, BIT_RATE,
 			META_ROI_INFO, MIN_QUALITY, BITRATE_BOOST, VBV_DELAY,
 			PEAK_BITRATE, SLICE_MODE, CONTENT_ADAPTIVE_CODING,
-			BLUR_TYPES, LOWLATENCY_MODE},
+			BLUR_TYPES, LOWLATENCY_MODE, META_TRANSCODING_STAT_INFO},
 		msm_vidc_adjust_bitrate_mode,
 		msm_vidc_set_u32_enum},
 
@@ -2129,7 +2133,7 @@ static struct msm_platform_inst_cap_dependency instance_cap_dependency_data_pine
 			P_FRAME_QP, B_FRAME_QP, CONSTANT_QUALITY, ENH_LAYER_COUNT,
 			BIT_RATE, META_ROI_INFO, MIN_QUALITY, BITRATE_BOOST, VBV_DELAY,
 			PEAK_BITRATE, SLICE_MODE, CONTENT_ADAPTIVE_CODING,
-			BLUR_TYPES, LOWLATENCY_MODE},
+			BLUR_TYPES, LOWLATENCY_MODE, META_EVA_STATS, META_TRANSCODING_STAT_INFO},
 		msm_vidc_adjust_bitrate_mode,
 		msm_vidc_set_u32_enum},
 
@@ -2374,7 +2378,12 @@ static struct msm_platform_inst_cap_dependency instance_cap_dependency_data_pine
 		NULL,
 		msm_vidc_set_u32_enum},
 
-	{PROFILE, ENC|DEC, HEVC|HEIC,
+	{PROFILE, ENC, HEVC|HEIC,
+		{META_SEI_MASTERING_DISP, META_SEI_CLL, META_HDR10PLUS},
+		msm_vidc_adjust_profile,
+		msm_vidc_set_u32_enum},
+
+	{PROFILE, DEC, HEVC|HEIC,
 		{0},
 		msm_vidc_adjust_profile,
 		msm_vidc_set_u32_enum},
@@ -2549,11 +2558,10 @@ static struct msm_platform_inst_cap_dependency instance_cap_dependency_data_pine
 		msm_vidc_adjust_all_intra,
 		NULL},
 
-	{META_EVA_STATS, ENC, H264|HEVC,
-		{ENH_LAYER_COUNT, REQUEST_PREPROCESS}},
-
-	{META_EVA_STATS, ENC, HEIC,
-		{0}},
+	{META_EVA_STATS, ENC, HEVC,
+		{0},
+		msm_vidc_adjust_eva_stats,
+		NULL},
 
 	{META_ROI_INFO, ENC, H264|HEVC,
 		{MIN_QUALITY, IR_PERIOD, BLUR_TYPES},
@@ -2579,6 +2587,26 @@ static struct msm_platform_inst_cap_dependency instance_cap_dependency_data_pine
 		{0},
 		NULL,
 		msm_vidc_set_signal_color_info},
+
+	{META_SEI_MASTERING_DISP, ENC, HEVC|HEIC,
+		{0},
+		msm_vidc_adjust_sei_mastering_disp,
+		NULL},
+
+	{META_SEI_CLL, ENC, HEVC|HEIC,
+		{0},
+		msm_vidc_adjust_sei_cll,
+		NULL},
+
+	{META_HDR10PLUS, ENC, HEVC|HEIC,
+		{0},
+		msm_vidc_adjust_hdr10plus,
+		NULL},
+
+	{META_TRANSCODING_STAT_INFO, ENC, HEVC|H264,
+		{0},
+		msm_vidc_adjust_transcoding_stats,
+		NULL},
 };
 
 /* Default UBWC config for LPDDR5 */

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

@@ -148,6 +148,7 @@ enum hfi_property_mode_type {
 	HFI_MODE_PORT_SETTINGS_CHANGE = 0x00000001,
 	HFI_MODE_PROPERTY             = 0x00000002,
 	HFI_MODE_METADATA             = 0x00000004,
+	HFI_MODE_DYNAMIC_METADATA     = 0x00000005,
 };
 
 enum hfi_reserve_type {

+ 34 - 2
driver/vidc/inc/msm_vidc_driver.h

@@ -151,6 +151,20 @@ static inline bool is_meta_tx_inp_enabled(struct msm_vidc_inst *inst, u32 cap)
 	return enabled;
 }
 
+static inline bool is_dyn_meta_tx_inp_enabled(struct msm_vidc_inst *inst, u32 cap)
+{
+	bool enabled = false;
+
+	if (!is_meta_cap(inst, cap))
+		return false;
+
+	if (inst->capabilities->cap[cap].value & MSM_VIDC_META_DYN_ENABLE &&
+		inst->capabilities->cap[cap].value & MSM_VIDC_META_TX_INPUT)
+		enabled = true;
+
+	return enabled;
+}
+
 static inline bool is_meta_tx_out_enabled(struct msm_vidc_inst *inst, u32 cap)
 {
 	bool enabled = false;
@@ -165,13 +179,28 @@ static inline bool is_meta_tx_out_enabled(struct msm_vidc_inst *inst, u32 cap)
 	return enabled;
 }
 
+static inline bool is_dyn_meta_tx_out_enabled(struct msm_vidc_inst *inst, u32 cap)
+{
+	bool enabled = false;
+
+	if (!is_meta_cap(inst, cap))
+		return false;
+
+	if (inst->capabilities->cap[cap].value & MSM_VIDC_META_DYN_ENABLE &&
+		inst->capabilities->cap[cap].value & MSM_VIDC_META_TX_OUTPUT)
+		enabled = true;
+
+	return enabled;
+}
+
 static inline bool is_any_meta_tx_out_enabled(struct msm_vidc_inst *inst)
 {
 	bool enabled = false;
 	u32 i;
 
 	for (i = INST_CAP_NONE + 1; i < INST_CAP_MAX; i++) {
-		if (is_meta_tx_out_enabled(inst, i)) {
+		if (is_meta_tx_out_enabled(inst, i) ||
+			is_dyn_meta_tx_out_enabled(inst, i)) {
 			enabled = true;
 			break;
 		}
@@ -186,7 +215,8 @@ static inline bool is_any_meta_tx_inp_enabled(struct msm_vidc_inst *inst)
 	u32 i;
 
 	for (i = INST_CAP_NONE + 1; i < INST_CAP_MAX; i++) {
-		if (is_meta_tx_inp_enabled(inst, i)) {
+		if (is_meta_tx_inp_enabled(inst, i) ||
+			is_dyn_meta_tx_inp_enabled(inst, i)) {
 			enabled = true;
 			break;
 		}
@@ -202,6 +232,7 @@ static inline bool is_input_meta_enabled(struct msm_vidc_inst *inst)
 
 	for (i = INST_CAP_NONE + 1; i < INST_CAP_MAX; i++) {
 		if (is_meta_tx_inp_enabled(inst, i) ||
+			is_dyn_meta_tx_inp_enabled(inst, i) ||
 			is_meta_rx_inp_enabled(inst, i)) {
 			enabled = true;
 			break;
@@ -218,6 +249,7 @@ static inline bool is_output_meta_enabled(struct msm_vidc_inst *inst)
 
 	for (i = INST_CAP_NONE + 1; i < INST_CAP_MAX; i++) {
 		if (is_meta_tx_out_enabled(inst, i) ||
+			is_dyn_meta_tx_out_enabled(inst, i) ||
 			is_meta_rx_out_enabled(inst, i)) {
 			enabled = true;
 			break;

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

@@ -43,7 +43,8 @@ enum msm_vidc_metadata_bits {
 	MSM_VIDC_META_TX_OUTPUT        = 0x4,
 	MSM_VIDC_META_RX_INPUT         = 0x8,
 	MSM_VIDC_META_RX_OUTPUT        = 0x10,
-	MSM_VIDC_META_MAX              = 0x20,
+	MSM_VIDC_META_DYN_ENABLE       = 0x20,
+	MSM_VIDC_META_MAX              = 0x40,
 };
 
 #define MSM_VIDC_METADATA_SIZE             (4 * 4096) /* 16 KB */
@@ -102,6 +103,9 @@ enum msm_vidc_metadata_bits {
 #define MAX_LTR_FRAME_COUNT_5                 5
 #define MAX_LTR_FRAME_COUNT_2                 2
 #define MAX_ENC_RING_BUF_COUNT                5 /* to be tuned */
+#define MAX_TRANSCODING_STATS_FRAME_RATE     60
+#define MAX_TRANSCODING_STATS_WIDTH        4096
+#define MAX_TRANSCODING_STATS_HEIGHT       2304
 
 #define DCVS_WINDOW 16
 #define ENC_FPS_WINDOW 3

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

@@ -774,6 +774,53 @@ static int msm_venc_metadata_delivery(struct msm_vidc_inst *inst,
 	return rc;
 }
 
+static int msm_venc_dynamic_metadata_delivery(struct msm_vidc_inst *inst,
+	enum msm_vidc_port_type port)
+{
+	int rc = 0;
+	u32 payload[32] = {0};
+	u32 i, count = 0;
+	struct msm_vidc_inst_capability *capability;
+
+	if (!inst || !inst->capabilities) {
+		d_vpr_e("%s: invalid params\n", __func__);
+		return -EINVAL;
+	}
+	i_vpr_h(inst, "%s()\n", __func__);
+
+	capability = inst->capabilities;
+	payload[0] = HFI_MODE_DYNAMIC_METADATA;
+
+	if (port != INPUT_PORT) {
+		i_vpr_e(inst, "%s: invalid port: %d\n", __func__, port);
+		return -EINVAL;
+	}
+
+	for (i = INST_CAP_NONE + 1; i < INST_CAP_MAX; i++) {
+		if (is_dyn_meta_tx_inp_enabled(inst, i)) {
+			if (count + 1 >= sizeof(payload) / sizeof(u32)) {
+				i_vpr_e(inst,
+					"%s: dynamic input metadatas (%d) exceeded limit (%d)\n",
+					__func__, count, sizeof(payload) / sizeof(u32));
+				return -EINVAL;
+			}
+			payload[count + 1] = capability->cap[i].hfi_id;
+			count++;
+		}
+	}
+
+	rc = venus_hfi_session_command(inst,
+			HFI_CMD_DELIVERY_MODE,
+			port,
+			HFI_PAYLOAD_U32_ARRAY,
+			&payload[0],
+			(count + 1) * sizeof(u32));
+	if (rc)
+		return rc;
+
+	return rc;
+}
+
 static int msm_venc_metadata_subscription(struct msm_vidc_inst *inst,
 	enum msm_vidc_port_type port)
 {
@@ -902,6 +949,10 @@ int msm_venc_streamon_input(struct msm_vidc_inst *inst)
 	if (rc)
 		goto error;
 
+	rc = msm_venc_dynamic_metadata_delivery(inst, INPUT_PORT);
+	if (rc)
+		goto error;
+
 	rc = msm_vidc_process_streamon_input(inst);
 	if (rc)
 		goto error;

+ 2 - 1
include/uapi/vidc/media/v4l2_vidc_extensions.h

@@ -97,7 +97,8 @@ enum v4l2_mpeg_vidc_metadata_bits {
 	V4L2_MPEG_VIDC_META_TX_OUTPUT        = 0x4,
 	V4L2_MPEG_VIDC_META_RX_INPUT         = 0x8,
 	V4L2_MPEG_VIDC_META_RX_OUTPUT        = 0x10,
-	V4L2_MPEG_VIDC_META_MAX              = 0x20,
+	V4L2_MPEG_VIDC_META_DYN_ENABLE       = 0x20,
+	V4L2_MPEG_VIDC_META_MAX              = 0x40,
 };
 
 #define V4L2_CID_MPEG_VIDC_METADATA_LTR_MARK_USE_DETAILS                      \