Pārlūkot izejas kodu

video: driver: Enable encoder input CR stats

Enable encoder input Compression Ratio (CR) stats.
Input CR stats are provided by clients for each input buffer
and used in bandwidth calculations.

Change-Id: Ibd910118837148b0b9dcc288069237f9a2d8f225
Signed-off-by: Chinmay Sawarkar <[email protected]>
Signed-off-by: Mihir Ganu <[email protected]>
Chinmay Sawarkar 4 gadi atpakaļ
vecāks
revīzija
7b9c3cb048

+ 5 - 0
driver/platform/waipio/src/msm_vidc_waipio.c

@@ -1084,6 +1084,11 @@ static struct msm_platform_inst_capability instance_data_waipio[] = {
 		{0}, {0},
 		NULL, NULL},
 
+	{ENC_IP_CR, ENC, CODECS_ALL,
+		0, S32_MAX, 1, 0,
+		V4L2_CID_MPEG_VIDC_ENC_INPUT_COMPRESSION_RATIO,
+		0, CAP_FLAG_DYNAMIC_ALLOWED},
+
 	{META_LTR_MARK_USE, ENC, H264|HEVC,
 		V4L2_MPEG_MSM_VIDC_DISABLE, V4L2_MPEG_MSM_VIDC_ENABLE,
 		1, V4L2_MPEG_MSM_VIDC_DISABLE,

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

@@ -419,6 +419,7 @@ enum msm_vidc_inst_capability_type {
 	RAP_FRAME,
 	SEQ_CHANGE_AT_SYNC_FRAME,
 	PRIORITY,
+	ENC_IP_CR,
 	META_LTR_MARK_USE,
 	META_DPB_MISR,
 	META_OPB_MISR,

+ 1 - 0
driver/vidc/src/msm_vidc.c

@@ -777,6 +777,7 @@ void *msm_vidc_open(void *vidc_core, u32 session_type)
 	INIT_LIST_HEAD(&inst->mappings.vpss.list);
 	INIT_LIST_HEAD(&inst->children.list);
 	INIT_LIST_HEAD(&inst->firmware.list);
+	INIT_LIST_HEAD(&inst->enc_input_crs);
 	for (i = 0; i < MAX_SIGNAL; i++)
 		init_completion(&inst->completions[i]);
 

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

@@ -162,6 +162,7 @@ static const struct msm_vidc_cap_name cap_name_arr[] = {
 	{RAP_FRAME,                      "RAP_FRAME"                  },
 	{SEQ_CHANGE_AT_SYNC_FRAME,       "SEQ_CHANGE_AT_SYNC_FRAME"   },
 	{PRIORITY,                       "PRIORITY"                   },
+	{ENC_IP_CR,                      "ENC_IP_CR"                  },
 	{META_LTR_MARK_USE,              "META_LTR_MARK_USE"          },
 	{META_DPB_MISR,                  "META_DPB_MISR"              },
 	{META_OPB_MISR,                  "META_OPB_MISR"              },
@@ -1082,6 +1083,7 @@ bool msm_vidc_allow_s_ctrl(struct msm_vidc_inst *inst, u32 id)
 			case V4L2_CID_MPEG_VIDC_VIDEO_BLUR_TYPES:
 			case V4L2_CID_MPEG_VIDC_VIDEO_BLUR_RESOLUTION:
 			case V4L2_CID_MPEG_VIDEO_CONSTANT_QUALITY:
+			case V4L2_CID_MPEG_VIDC_ENC_INPUT_COMPRESSION_RATIO:
 				allow = true;
 				break;
 			default:
@@ -2121,11 +2123,47 @@ int msm_vidc_queue_buffer_batch(struct msm_vidc_inst *inst)
 	return 0;
 }
 
+void msm_vidc_update_input_cr(struct msm_vidc_inst *inst, u32 idx, u32 cr)
+{
+	struct msm_vidc_input_cr_data *temp, *next;
+	bool found = false;
+
+	list_for_each_entry_safe(temp, next, &inst->enc_input_crs, list) {
+		if (temp->index == idx) {
+			temp->input_cr = cr;
+			found = true;
+			break;
+		}
+	}
+	if (!found) {
+		temp = kzalloc(sizeof(*temp), GFP_KERNEL);
+		if (!temp) {
+			i_vpr_e(inst, "%s: malloc failure.\n", __func__);
+			return;
+		}
+		temp->index = idx;
+		temp->input_cr = cr;
+		list_add_tail(&temp->list, &inst->enc_input_crs);
+	}
+}
+
+void msm_vidc_free_input_cr_list(struct msm_vidc_inst *inst)
+{
+	struct msm_vidc_input_cr_data *temp, *next;
+
+	list_for_each_entry_safe(temp, next, &inst->enc_input_crs, list) {
+		list_del(&temp->list);
+		kfree(temp);
+	}
+	INIT_LIST_HEAD(&inst->enc_input_crs);
+}
+
 int msm_vidc_queue_buffer_single(struct msm_vidc_inst *inst, struct vb2_buffer *vb2)
 {
 	int rc = 0;
 	struct msm_vidc_buffer *buf;
 	enum msm_vidc_allow allow;
+	u32 cr = 0;
 
 	if (!inst || !vb2) {
 		d_vpr_e("%s: invalid params\n", __func__);
@@ -2146,6 +2184,11 @@ int msm_vidc_queue_buffer_single(struct msm_vidc_inst *inst, struct vb2_buffer *
 	}
 
 	if (buf->type == MSM_VIDC_BUF_INPUT) {
+		if (is_encode_session(inst)) {
+			cr = inst->capabilities->cap[ENC_IP_CR].value;
+			msm_vidc_update_input_cr(inst, vb2->index, cr);
+			inst->capabilities->cap[ENC_IP_CR].value = 0;
+		}
 		inst->power.buffer_counter++;
 		msm_vidc_scale_power(inst, true);
 	}
@@ -3583,6 +3626,7 @@ static void msm_vidc_close_helper(struct kref *kref)
 		msm_vdec_inst_deinit(inst);
 	else if (is_encode_session(inst))
 		msm_venc_inst_deinit(inst);
+	msm_vidc_free_input_cr_list(inst);
 	kfree(inst->capabilities);
 	if (inst->response_workq)
 		destroy_workqueue(inst->response_workq);

+ 7 - 1
driver/vidc/src/msm_vidc_power.c

@@ -118,6 +118,7 @@ exit:
 static int fill_dynamic_stats(struct msm_vidc_inst *inst,
 	struct vidc_bus_vote_data *vote_data)
 {
+	struct msm_vidc_input_cr_data *temp, *next;
 	u32 max_cr = MSM_VIDC_MIN_UBWC_COMPRESSION_RATIO;
 	u32 max_cf = MSM_VIDC_MIN_UBWC_COMPLEXITY_FACTOR;
 	u32 max_input_cr = MSM_VIDC_MIN_UBWC_COMPRESSION_RATIO;
@@ -129,7 +130,12 @@ static int fill_dynamic_stats(struct msm_vidc_inst *inst,
 	min_cr = inst->power.fw_cr;
 	max_cf = inst->power.fw_cf;
 	max_cf = max_cf / ((msm_vidc_get_mbs_per_frame(inst)) / (32 * 8) * 3) / 2;
-	// Todo: min_input_cr = 0;
+
+	list_for_each_entry_safe(temp, next, &inst->enc_input_crs, list) {
+		min_input_cr = min(min_input_cr, temp->input_cr);
+		max_input_cr = max(max_input_cr, temp->input_cr);
+	}
+
 
 	/* Sanitize CF values from HW */
 	max_cf = min_t(u32, max_cf, MSM_VIDC_MAX_UBWC_COMPLEXITY_FACTOR);