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:

committed by
Gerrit - the friendly Code Review server

parent
d172684c07
commit
2719badd2b
@@ -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);
|
||||
|
@@ -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,
|
||||
|
@@ -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,
|
||||
|
@@ -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,
|
||||
|
@@ -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;
|
||||
|
@@ -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__,
|
||||
|
Reference in New Issue
Block a user