Browse Source

video: driver: add dpb buffer handling for b2b ipsc cases

Currently MSM_VIDC_BUF_DPB buffer allocated and queued to firmware
as part of output port streamon. Sometimes firmware raises b2b ipsc
with only change in fw_min_count. So client will not follow port
reconfig sequence and calls directly HFI_CMD_RESUME on output port.
So firmware holds only prev set of DPB buffers, which is not sufficient
and it continues to wait for further DPB buffers and that is leading
to stall and testcase fails. So added change to requeue new set of
DPB buffers, incase of b2b ipsc(with only change in count).

Change-Id: I213c752be4ca9dc16f838ab2990c996c4d78e95f
Signed-off-by: Govindaraj Rajagopal <[email protected]>
Govindaraj Rajagopal 3 years ago
parent
commit
839a329864
2 changed files with 58 additions and 9 deletions
  1. 2 0
      driver/vidc/inc/msm_vidc_driver.h
  2. 56 9
      driver/vidc/src/msm_vdec.c

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

@@ -282,6 +282,8 @@ const char *allow_name(enum msm_vidc_allow allow);
 const char *state_name(enum msm_vidc_inst_state state);
 int msm_vidc_change_inst_state(struct msm_vidc_inst *inst,
 	enum msm_vidc_inst_state request_state, const char *func);
+int msm_vidc_create_internal_buffer(struct msm_vidc_inst *inst,
+	enum msm_vidc_buffer_type buffer_type, u32 index);
 int msm_vidc_get_internal_buffers(struct msm_vidc_inst *inst,
 	enum msm_vidc_buffer_type buffer_type);
 int msm_vidc_create_internal_buffers(struct msm_vidc_inst *inst,

+ 56 - 9
driver/vidc/src/msm_vdec.c

@@ -2068,6 +2068,52 @@ int msm_vdec_qbuf(struct msm_vidc_inst *inst, struct vb2_buffer *vb2)
 	return rc;
 }
 
+static msm_vdec_alloc_and_queue_additional_dpb_buffers(struct msm_vidc_inst *inst)
+{
+	struct msm_vidc_buffers *buffers;
+	struct msm_vidc_buffer *buffer = NULL;
+	int i, cur_min_count = 0, rc = 0;
+
+	if (!inst) {
+		d_vpr_e("%s: invalid params\n", __func__);
+		return -EINVAL;
+	}
+
+	/* get latest min_count and size */
+	rc = msm_vidc_get_internal_buffers(inst, MSM_VIDC_BUF_DPB);
+	if (rc)
+		return rc;
+
+	buffers = msm_vidc_get_buffers(inst, MSM_VIDC_BUF_DPB, __func__);
+	if (!buffers)
+		return -EINVAL;
+
+	/* get current min_count */
+	list_for_each_entry(buffer, &buffers->list, list)
+		cur_min_count++;
+
+	/* skip alloc and queue */
+	if (cur_min_count >= buffers->min_count)
+		return 0;
+
+	i_vpr_h(inst, "%s: dpb buffer count increased from %u -> %u\n",
+		__func__, cur_min_count, buffers->min_count);
+
+	/* allocate additional DPB buffers */
+	for (i = cur_min_count; i < buffers->min_count; i++) {
+		rc = msm_vidc_create_internal_buffer(inst, MSM_VIDC_BUF_DPB, i);
+		if (rc)
+			return rc;
+	}
+
+	/* queue additional DPB buffers */
+	rc = msm_vidc_queue_internal_buffers(inst, MSM_VIDC_BUF_DPB);
+	if (rc)
+		return rc;
+
+	return 0;
+}
+
 int msm_vdec_process_cmd(struct msm_vidc_inst *inst, u32 cmd)
 {
 	int rc = 0;
@@ -2127,21 +2173,22 @@ int msm_vdec_process_cmd(struct msm_vidc_inst *inst, u32 cmd)
 		msm_vidc_allow_dcvs(inst);
 		msm_vidc_power_data_reset(inst);
 
-		/* print final buffer counts & size details */
-		msm_vidc_print_buffer_info(inst);
-
 		rc = msm_vidc_set_seq_change_at_sync_frame(inst);
 		if (rc)
 			return rc;
 
-		rc = venus_hfi_session_command(inst,
-				HFI_CMD_RESUME,
-				port,
-				HFI_PAYLOAD_NONE,
-				NULL,
-				0);
+		/* allocate and queue extra dpb buffers */
+		rc = msm_vdec_alloc_and_queue_additional_dpb_buffers(inst);
+		if (rc)
+			return rc;
+
+		/* print final buffer counts & size details */
+		msm_vidc_print_buffer_info(inst);
+
+		rc = msm_vdec_session_resume(inst, port);
 		if (rc)
 			return rc;
+
 	} else {
 		i_vpr_e(inst, "%s: unknown cmd %d\n", __func__, cmd);
 		return -EINVAL;