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 <majja@codeaurora.org>
This commit is contained in:
Maheshwar Ajja
2021-01-26 22:42:15 -08:00
committed by Gerrit - the friendly Code Review server
parent d172684c07
commit 2719badd2b
6 changed files with 69 additions and 38 deletions

View File

@@ -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);

View File

@@ -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,

View File

@@ -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,

View File

@@ -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,

View File

@@ -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;

View File

@@ -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:
allow = msm_vidc_allow_input_psc(inst);
if (!allow) {
s_vpr_e(inst->sid, "%s: input psc not allowed\n", __func__);
break;
}
rc = handle_session_response_work(inst, resp_work);
if (!rc)
rc = msm_vidc_state_change_input_psc(inst);
{
enum msm_vidc_allow allow = MSM_VIDC_DISALLOW;
/* either handle input psc or state change failed */
if (rc)
allow = msm_vidc_allow_input_psc(inst);
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__);
}
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__,