浏览代码

video: driver: Introduce a property to set COMV bufcount

Certain codecs/use cases require larger COMV buffer sizes to achieve
performance. Introduce a property to set COMV bufcount and calculate
COMV buffer size based on the bufcount.

Change-Id: Ib0ed8afe77708dc453cbcc121bcd8606db637152
Signed-off-by: Mihir Ganu <[email protected]>
Mihir Ganu 3 年之前
父节点
当前提交
1e87ceec2b

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

@@ -486,6 +486,9 @@ static struct msm_platform_inst_capability instance_cap_data_kalama[] = {
 	{LOWLATENCY_MAX_BITRATE, ENC, H264|HEVC, 0,
 		70000000, 1, 70000000},
 
+	{NUM_COMV, DEC, CODECS_ALL,
+		0, INT_MAX, 1, 0},
+
 	{LOSSLESS, ENC, HEVC,
 		V4L2_MPEG_MSM_VIDC_DISABLE, V4L2_MPEG_MSM_VIDC_ENABLE,
 		1, V4L2_MPEG_MSM_VIDC_DISABLE,

+ 6 - 6
driver/variant/iris3/inc/hfi_buffer_iris3.h

@@ -386,7 +386,7 @@ typedef HFI_U32 HFI_BOOL;
 	} while (0)
 
 #define HFI_BUFFER_COMV_H264D(coMV_size, frame_width, \
-			frame_height, _yuv_bufcount_min) \
+			frame_height, _comv_bufcount) \
 	do \
 	{ \
 		HFI_U32 frame_width_in_mbs = ((frame_width + 15) >> 4); \
@@ -413,7 +413,7 @@ typedef HFI_U32 HFI_BOOL;
 		size_colloc = HFI_ALIGN(size_colloc, \
 				BUFFER_ALIGNMENT_512_BYTES); \
 		size_colloc += (col_zero_size + SIZE_H264D_BUFTAB_T * 2); \
-		coMV_size = size_colloc * (_yuv_bufcount_min); \
+		coMV_size = size_colloc * (_comv_bufcount); \
 		coMV_size += BUFFER_ALIGNMENT_512_BYTES; \
 	} while (0)
 
@@ -597,13 +597,13 @@ typedef HFI_U32 HFI_BOOL;
 	} while (0)
 
 #define HFI_BUFFER_COMV_H265D(_size, frame_width, frame_height, \
-							_yuv_bufcount_min) \
+							_comv_bufcount) \
 	do \
 	{ \
 		_size = HFI_ALIGN(((((frame_width + 15) >> 4) * \
 			((frame_height + 15) >> 4)) << 8), \
 			BUFFER_ALIGNMENT_512_BYTES); \
-		_size *= _yuv_bufcount_min; \
+		_size *= _comv_bufcount; \
 		_size += BUFFER_ALIGNMENT_512_BYTES; \
 	} while (0)
 
@@ -893,14 +893,14 @@ _yuv_bufcount_min, is_opb, num_vpp_pipes)           \
 #define AV1D_MAX_TILE_COLS     64
 
 #define HFI_BUFFER_COMV_AV1D(_size, frame_width, frame_height, \
-				_yuv_bufcount_min) \
+				_comv_bufcount) \
 	do { \
 		_size = 2 * HFI_ALIGN(MAX(((frame_width + 63) / 64) * \
 				((frame_height + 63) / 64) * 512, \
 				((frame_width + 127) / 128) * \
 				((frame_height + 127) / 128) * 2816), \
 				VENUS_DMA_ALIGNMENT); \
-		_size *= _yuv_bufcount_min; \
+		_size *= _comv_bufcount; \
 	} while (0)
 
 #define SIZE_AV1D_LB_FE_TOP_DATA(frame_width, frame_height) \

+ 23 - 7
driver/variant/iris3/src/msm_vidc_buffer_iris3.c

@@ -68,10 +68,10 @@ static u32 msm_vidc_decoder_bin_size_iris3(struct msm_vidc_inst *inst)
 static u32 msm_vidc_decoder_comv_size_iris3(struct msm_vidc_inst* inst)
 {
 	u32 size = 0;
-	u32 width, height, out_min_count, vpp_delay;
+	u32 width, height, num_comv, vpp_delay;
 	struct v4l2_format *f;
 
-	if (!inst || !inst->core) {
+	if (!inst || !inst->core || !inst->capabilities) {
 		d_vpr_e("%s: invalid params\n", __func__);
 		return size;
 	}
@@ -79,17 +79,33 @@ static u32 msm_vidc_decoder_comv_size_iris3(struct msm_vidc_inst* inst)
 	f = &inst->fmts[INPUT_PORT];
 	width = f->fmt.pix_mp.width;
 	height = f->fmt.pix_mp.height;
+
+	if (inst->codec == MSM_VIDC_AV1) {
+		/*
+		 * AV1 requires larger COMV buffer size to meet performance
+		 * for certain use cases. Increase the COMV buffer size by
+		 * increasing COMV bufcount. Use lower count for 8k to
+		 * achieve performance but save memory.
+		 */
+		if (res_is_greater_than(width, height, 4096, 2176))
+			num_comv = inst->buffers.output.min_count + 3;
+		else
+			num_comv = inst->buffers.output.min_count + 7;
+	} else {
+		num_comv = inst->buffers.output.min_count;
+	}
+	msm_vidc_update_cap_value(inst, NUM_COMV, num_comv, __func__);
+
 	if (inst->decode_vpp_delay.enable)
 		vpp_delay = inst->decode_vpp_delay.size;
 	else
 		vpp_delay = DEFAULT_BSE_VPP_DELAY;
-	out_min_count = inst->buffers.output.min_count;
-	out_min_count = max(vpp_delay + 1, out_min_count);
+	num_comv = max(vpp_delay + 1, num_comv);
 
 	if (inst->codec == MSM_VIDC_H264) {
-		HFI_BUFFER_COMV_H264D(size, width, height, out_min_count);
+		HFI_BUFFER_COMV_H264D(size, width, height, num_comv);
 	} else if (inst->codec == MSM_VIDC_HEVC || inst->codec == MSM_VIDC_HEIC) {
-		HFI_BUFFER_COMV_H265D(size, width, height, out_min_count);
+		HFI_BUFFER_COMV_H265D(size, width, height, num_comv);
 	} else if (inst->codec == MSM_VIDC_AV1) {
 		/*
 		 * When DRAP is enabled, COMV buffer is part of PERSIST buffer and
@@ -99,7 +115,7 @@ static u32 msm_vidc_decoder_comv_size_iris3(struct msm_vidc_inst* inst)
 		if (inst->capabilities->cap[DRAP].value)
 			size = 0;
 		else
-			HFI_BUFFER_COMV_AV1D(size, width, height, out_min_count);
+			HFI_BUFFER_COMV_AV1D(size, width, height, num_comv);
 	}
 
 	i_vpr_l(inst, "%s: size %d\n", __func__, size);

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

@@ -565,6 +565,8 @@ enum hfi_saliency_type {
 
 #define HFI_PROP_DOLBY_RPU_METADATA                             0x03000192
 
+#define HFI_PROP_COMV_BUFFER_COUNT                              0x03000193
+
 #define HFI_PROP_END                                            0x03FFFFFF
 
 #define HFI_SESSION_ERROR_BEGIN                                 0x04000000

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

@@ -30,6 +30,7 @@ int msm_vdec_output_port_settings_change(struct msm_vidc_inst *inst);
 int msm_vdec_process_cmd(struct msm_vidc_inst *inst, u32 cmd);
 int msm_vdec_handle_release_buffer(struct msm_vidc_inst *inst,
 	struct msm_vidc_buffer *buf);
+int msm_vdec_set_num_comv(struct msm_vidc_inst *inst);
 int msm_vdec_get_input_internal_buffers(struct msm_vidc_inst *inst);
 int msm_vdec_create_input_internal_buffers(struct msm_vidc_inst *inst);
 int msm_vdec_queue_input_internal_buffers(struct msm_vidc_inst *inst);

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

@@ -501,6 +501,7 @@ enum msm_vidc_inst_capability_type {
 	ALLINTRA_MAX_BITRATE,
 	LOWLATENCY_MAX_BITRATE,
 	LAST_FLAG_EVENT_ENABLE,
+	NUM_COMV,
 	/* place all root(no parent) enums before this line */
 
 	PROFILE,

+ 27 - 0
driver/vidc/src/msm_vdec.c

@@ -1224,6 +1224,33 @@ int msm_vdec_init_input_subcr_params(struct msm_vidc_inst *inst)
 	return 0;
 }
 
+int msm_vdec_set_num_comv(struct msm_vidc_inst *inst)
+{
+	int rc = 0;
+	u32 num_comv = 0;
+
+	if (!inst || !inst->capabilities) {
+		d_vpr_e("%s: invalid params\n", __func__);
+		return -EINVAL;
+	}
+
+	num_comv = inst->capabilities->cap[NUM_COMV].value;
+	i_vpr_h(inst, "%s: num COMV: %d", __func__, num_comv);
+	rc = venus_hfi_session_property(inst,
+			HFI_PROP_COMV_BUFFER_COUNT,
+			HFI_HOST_FLAGS_NONE,
+			get_hfi_port(inst, INPUT_PORT),
+			HFI_PAYLOAD_U32,
+			&num_comv,
+			sizeof(u32));
+	if (rc) {
+		i_vpr_e(inst, "%s: set property failed\n", __func__);
+		return rc;
+	}
+
+	return rc;
+}
+
 static int msm_vdec_read_input_subcr_params(struct msm_vidc_inst *inst)
 {
 	struct msm_vidc_subscription_params subsc_params;

+ 1 - 4
driver/vidc/src/msm_vidc_buffer.c

@@ -70,11 +70,8 @@ u32 msm_vidc_output_min_count(struct msm_vidc_inst *inst)
 			output_min_count = 4;
 			break;
 		case MSM_VIDC_VP9:
-			output_min_count = 9;
-			break;
 		case MSM_VIDC_AV1:
-			// TODO: needs review
-			output_min_count = 11;
+			output_min_count = 9;
 			break;
 		case MSM_VIDC_HEIC:
 			output_min_count = 3;

+ 7 - 0
driver/vidc/src/msm_vidc_driver.c

@@ -195,6 +195,7 @@ static const struct msm_vidc_cap_name cap_name_arr[] = {
 	{ALLINTRA_MAX_BITRATE,           "ALLINTRA_MAX_BITRATE"       },
 	{LOWLATENCY_MAX_BITRATE,         "LOWLATENCY_MAX_BITRATE"     },
 	{LAST_FLAG_EVENT_ENABLE,         "LAST_FLAG_EVENT_ENABLE"     },
+	{NUM_COMV,                       "NUM_COMV"                   },
 	{PROFILE,                        "PROFILE"                    },
 	{ENH_LAYER_COUNT,                "ENH_LAYER_COUNT"            },
 	{BIT_RATE,                       "BIT_RATE"                   },
@@ -3946,6 +3947,12 @@ int msm_vidc_queue_internal_buffers(struct msm_vidc_inst *inst,
 		return 0;
 	}
 
+	if (is_decode_session(inst) && buffer_type == MSM_VIDC_BUF_COMV) {
+		rc = msm_vdec_set_num_comv(inst);
+		if (rc)
+			return rc;
+	}
+
 	list_for_each_entry_safe(buffer, dummy, &buffers->list, list) {
 		/* do not queue pending release buffers */
 		if (buffer->flags & MSM_VIDC_ATTR_PENDING_RELEASE)