Bläddra i källkod

video: driver: amend stop and last flag processing

- do not ignore last flag buffer in last flag not allowed
  case also
- ignore stop command if input port is not streaming
  instead of returning -EBUSY error.
- defer input port settings change in few states instead of
  ignoring it.

Change-Id: I705f0c8ae2da899a5d262f6246aa65de5591ac26
Signed-off-by: Maheshwar Ajja <[email protected]>
Maheshwar Ajja 4 år sedan
förälder
incheckning
2719badd2b

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

@@ -276,12 +276,12 @@ void put_inst(struct msm_vidc_inst *inst);
 bool msm_vidc_allow_s_fmt(struct msm_vidc_inst *inst, u32 type);
 bool msm_vidc_allow_s_ctrl(struct msm_vidc_inst *inst, u32 id);
 bool msm_vidc_allow_reqbufs(struct msm_vidc_inst *inst, u32 type);
-bool msm_vidc_allow_stop(struct msm_vidc_inst *inst);
+enum msm_vidc_allow msm_vidc_allow_stop(struct msm_vidc_inst *inst);
 bool msm_vidc_allow_start(struct msm_vidc_inst *inst);
 bool msm_vidc_allow_streamon(struct msm_vidc_inst *inst, u32 type);
 bool msm_vidc_allow_streamoff(struct msm_vidc_inst *inst, u32 type);
 bool msm_vidc_allow_qbuf(struct msm_vidc_inst *inst);
-bool msm_vidc_allow_input_psc(struct msm_vidc_inst *inst);
+enum msm_vidc_allow msm_vidc_allow_input_psc(struct msm_vidc_inst *inst);
 bool msm_vidc_allow_last_flag(struct msm_vidc_inst *inst);
 int msm_vidc_state_change_streamon(struct msm_vidc_inst *inst, u32 type);
 int msm_vidc_state_change_streamoff(struct msm_vidc_inst *inst, u32 type);

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

@@ -713,6 +713,13 @@ struct msm_vidc_buffers {
 	bool                   reuse;
 };
 
+enum msm_vidc_allow {
+	MSM_VIDC_DISALLOW = 0,
+	MSM_VIDC_ALLOW,
+	MSM_VIDC_DEFER,
+	MSM_VIDC_IGNORE,
+};
+
 enum response_work_type {
 	RESP_WORK_INPUT_PSC = 1,
 	RESP_WORK_OUTPUT_PSC,

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

@@ -1564,6 +1564,7 @@ int msm_vdec_qbuf(struct msm_vidc_inst *inst, struct vb2_buffer *vb2)
 int msm_vdec_process_cmd(struct msm_vidc_inst *inst, u32 cmd)
 {
 	int rc = 0;
+	enum msm_vidc_allow allow = MSM_VIDC_DISALLOW;
 
 	if (!inst || !inst->core) {
 		d_vpr_e("%s: invalid params\n", __func__);
@@ -1571,8 +1572,13 @@ int msm_vdec_process_cmd(struct msm_vidc_inst *inst, u32 cmd)
 	}
 
 	if (cmd == V4L2_DEC_CMD_STOP) {
-		if (!msm_vidc_allow_stop(inst))
+		allow = msm_vidc_allow_stop(inst);
+		if (allow == MSM_VIDC_DISALLOW)
 			return -EBUSY;
+		else if (allow == MSM_VIDC_IGNORE)
+			return 0;
+		else if (allow != MSM_VIDC_ALLOW)
+			return -EINVAL;
 		rc = venus_hfi_session_command(inst,
 				HFI_CMD_DRAIN,
 				INPUT_PORT,

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

@@ -837,6 +837,7 @@ error:
 int msm_venc_process_cmd(struct msm_vidc_inst *inst, u32 cmd)
 {
 	int rc = 0;
+	enum msm_vidc_allow allow = MSM_VIDC_DISALLOW;
 
 	if (!inst || !inst->core) {
 		d_vpr_e("%s: invalid params\n", __func__);
@@ -844,8 +845,13 @@ int msm_venc_process_cmd(struct msm_vidc_inst *inst, u32 cmd)
 	}
 
 	if (cmd == V4L2_ENC_CMD_STOP) {
-		if (!msm_vidc_allow_stop(inst))
+		allow = msm_vidc_allow_stop(inst);
+		if (allow == MSM_VIDC_DISALLOW)
 			return -EBUSY;
+		else if (allow == MSM_VIDC_IGNORE)
+			return 0;
+		else if (allow != MSM_VIDC_ALLOW)
+			return -EINVAL;
 		rc = venus_hfi_session_command(inst,
 				HFI_CMD_DRAIN,
 				INPUT_PORT,

+ 22 - 14
driver/vidc/src/msm_vidc_driver.c

@@ -654,21 +654,29 @@ exit:
 	return allow;
 }
 
-bool msm_vidc_allow_stop(struct msm_vidc_inst *inst)
+enum msm_vidc_allow msm_vidc_allow_stop(struct msm_vidc_inst *inst)
 {
+	enum msm_vidc_allow allow = MSM_VIDC_DISALLOW;
+
 	if (!inst) {
 		d_vpr_e("%s: invalid params\n", __func__);
-		return false;
+		return allow;
 	}
 	if (inst->state == MSM_VIDC_START ||
 		inst->state == MSM_VIDC_DRC ||
 		inst->state == MSM_VIDC_DRC_LAST_FLAG ||
-		inst->state == MSM_VIDC_DRC_DRAIN)
-		return true;
-
-	s_vpr_e(inst->sid, "%s: not allowed in state %s\n",
+		inst->state == MSM_VIDC_DRC_DRAIN) {
+		allow = MSM_VIDC_ALLOW;
+	} else if (inst->state == MSM_VIDC_START_INPUT) {
+		allow = MSM_VIDC_IGNORE;
+		s_vpr_e(inst->sid, "%s: stop ignored in state %s\n",
 			__func__, state_name(inst->state));
-	return false;
+	} else {
+		s_vpr_e(inst->sid, "%s: stop not allowed in state %s\n",
+			__func__, state_name(inst->state));
+	}
+
+	return allow;
 }
 
 bool msm_vidc_allow_start(struct msm_vidc_inst *inst)
@@ -753,30 +761,30 @@ bool msm_vidc_allow_qbuf(struct msm_vidc_inst *inst)
 	}
 }
 
-bool msm_vidc_allow_input_psc(struct msm_vidc_inst *inst)
+enum msm_vidc_allow msm_vidc_allow_input_psc(struct msm_vidc_inst *inst)
 {
-	bool allow = false;
+	enum msm_vidc_allow allow = MSM_VIDC_DISALLOW;
 
 	if (!inst) {
 		d_vpr_e("%s: invalid params\n", __func__);
-		return false;
+		return MSM_VIDC_DISALLOW;
 	}
 	if (inst->state == MSM_VIDC_START ||
 		inst->state == MSM_VIDC_START_INPUT ||
 		inst->state == MSM_VIDC_DRAIN) {
-		allow = true;
+		allow = MSM_VIDC_ALLOW;
 	} else if (inst->state == MSM_VIDC_DRC ||
 		inst->state == MSM_VIDC_DRC_LAST_FLAG ||
 		inst->state == MSM_VIDC_DRC_DRAIN ||
 		inst->state == MSM_VIDC_DRC_DRAIN_LAST_FLAG ||
 		inst->state == MSM_VIDC_DRAIN_START_INPUT) {
-		s_vpr_h(inst->sid, "%s: input psc postponed, inst state %s\n",
+		s_vpr_h(inst->sid, "%s: defer input psc, inst state %s\n",
 				__func__, state_name(inst->state));
-		allow = false;
+		allow = MSM_VIDC_DEFER;
 	} else {
 		s_vpr_e(inst->sid, "%s: input psc in wrong state %s\n",
 				__func__, state_name(inst->state));
-		allow = false;
+		allow = MSM_VIDC_DISALLOW;
 	}
 
 	return allow;

+ 23 - 19
driver/vidc/src/venus_hfi_response.c

@@ -1191,7 +1191,6 @@ exit:
 void handle_session_response_work_handler(struct work_struct *work)
 {
 	int rc = 0;
-	bool allow = false;
 	struct msm_vidc_inst *inst;
 	struct response_work *resp_work, *dummy = NULL;
 
@@ -1206,37 +1205,42 @@ void handle_session_response_work_handler(struct work_struct *work)
 	list_for_each_entry_safe(resp_work, dummy, &inst->response_works, list) {
 		switch (resp_work->type) {
 		case RESP_WORK_INPUT_PSC:
+		{
+			enum msm_vidc_allow allow = MSM_VIDC_DISALLOW;
+
 			allow = msm_vidc_allow_input_psc(inst);
-			if (!allow) {
-				s_vpr_e(inst->sid, "%s: input psc not allowed\n", __func__);
+			if (allow == MSM_VIDC_DISALLOW) {
+				msm_vidc_change_inst_state(inst, MSM_VIDC_ERROR, __func__);
 				break;
+			} else if (allow == MSM_VIDC_DEFER) {
+				/* continue to next entry processing */
+				continue;
+			} else if (allow == MSM_VIDC_ALLOW) {
+				rc = handle_session_response_work(inst, resp_work);
+				if (!rc)
+					rc = msm_vidc_state_change_input_psc(inst);
+				/* either handle input psc or state change failed */
+				if (rc)
+					msm_vidc_change_inst_state(inst, MSM_VIDC_ERROR, __func__);
 			}
-			rc = handle_session_response_work(inst, resp_work);
-			if (!rc)
-				rc = msm_vidc_state_change_input_psc(inst);
-
-			/* either handle input psc or state change failed */
-			if (rc)
-				msm_vidc_change_inst_state(inst, MSM_VIDC_ERROR, __func__);
 			break;
+		}
 		case RESP_WORK_OUTPUT_PSC:
 			rc = handle_session_response_work(inst, resp_work);
 			if (rc)
 				msm_vidc_change_inst_state(inst, MSM_VIDC_ERROR, __func__);
 			break;
 		case RESP_WORK_LAST_FLAG:
-			allow = msm_vidc_allow_last_flag(inst);
-			if (!allow) {
-				s_vpr_e(inst->sid, "%s: last flag not allowed\n", __func__);
+			rc = handle_session_response_work(inst, resp_work);
+			if (rc) {
+				msm_vidc_change_inst_state(inst, MSM_VIDC_ERROR, __func__);
 				break;
 			}
-			rc = handle_session_response_work(inst, resp_work);
-			if (!rc)
+			if (msm_vidc_allow_last_flag(inst)) {
 				rc = msm_vidc_state_change_last_flag(inst);
-
-			/* either handle last flag or state change failed */
-			if (rc)
-				msm_vidc_change_inst_state(inst, MSM_VIDC_ERROR, __func__);
+				if (rc)
+					msm_vidc_change_inst_state(inst, MSM_VIDC_ERROR, __func__);
+			}
 			break;
 		default:
 			d_vpr_e("%s: invalid response work type %d\n", __func__,