video: driver: release internal buffer as part of start/resume
Change-Id: I45469c0a569fbc282aa1dbd217654e49eb50f54f Signed-off-by: Darshana Patil <quic_darshana@quicinc.com>
This commit is contained in:
@@ -30,5 +30,9 @@ int msm_vdec_output_port_settings_change(struct msm_vidc_inst *inst);
|
||||
int msm_vdec_process_cmd(struct msm_vidc_inst *inst, u32 cmd);
|
||||
int msm_vdec_handle_release_buffer(struct msm_vidc_inst *inst,
|
||||
struct msm_vidc_buffer *buf);
|
||||
int msm_vdec_get_input_internal_buffers(struct msm_vidc_inst *inst);
|
||||
int msm_vdec_create_input_internal_buffers(struct msm_vidc_inst *inst);
|
||||
int msm_vdec_queue_input_internal_buffers(struct msm_vidc_inst *inst);
|
||||
int msm_vdec_release_input_internal_buffers(struct msm_vidc_inst *inst);
|
||||
|
||||
#endif // _MSM_VDEC_H_
|
||||
|
@@ -523,7 +523,8 @@ int msm_vidc_state_change_drain_last_flag(struct msm_vidc_inst *inst);
|
||||
int msm_vidc_state_change_psc_last_flag(struct msm_vidc_inst *inst);
|
||||
int msm_vidc_process_drain(struct msm_vidc_inst *inst);
|
||||
int msm_vidc_process_resume(struct msm_vidc_inst *inst);
|
||||
int msm_vidc_process_streamon(struct msm_vidc_inst *inst, u32 type);
|
||||
int msm_vidc_process_streamon_input(struct msm_vidc_inst *inst);
|
||||
int msm_vidc_process_streamon_output(struct msm_vidc_inst *inst);
|
||||
int msm_vidc_process_stop_done(struct msm_vidc_inst *inst,
|
||||
enum signal_session_response signal_type);
|
||||
int msm_vidc_process_drain_done(struct msm_vidc_inst *inst);
|
||||
@@ -586,5 +587,6 @@ int msm_vidc_update_input_rate(struct msm_vidc_inst *inst, u64 time_us);
|
||||
int msm_vidc_get_input_rate(struct msm_vidc_inst *inst);
|
||||
int msm_vidc_get_frame_rate(struct msm_vidc_inst *inst);
|
||||
int msm_vidc_get_operating_rate(struct msm_vidc_inst *inst);
|
||||
int msm_vidc_alloc_and_queue_input_internal_buffers(struct msm_vidc_inst *inst);
|
||||
#endif // _MSM_VIDC_DRIVER_H_
|
||||
|
||||
|
@@ -755,7 +755,7 @@ static int msm_vdec_set_output_properties(struct msm_vidc_inst *inst)
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int msm_vdec_get_input_internal_buffers(struct msm_vidc_inst *inst)
|
||||
int msm_vdec_get_input_internal_buffers(struct msm_vidc_inst *inst)
|
||||
{
|
||||
int rc = 0;
|
||||
u32 i = 0;
|
||||
@@ -790,7 +790,7 @@ static int msm_vdec_get_output_internal_buffers(struct msm_vidc_inst *inst)
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int msm_vdec_create_input_internal_buffers(struct msm_vidc_inst *inst)
|
||||
int msm_vdec_create_input_internal_buffers(struct msm_vidc_inst *inst)
|
||||
{
|
||||
int rc = 0;
|
||||
u32 i = 0;
|
||||
@@ -815,7 +815,7 @@ static int msm_vdec_create_output_internal_buffers(struct msm_vidc_inst *inst)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int msm_vdec_queue_input_internal_buffers(struct msm_vidc_inst *inst)
|
||||
int msm_vdec_queue_input_internal_buffers(struct msm_vidc_inst *inst)
|
||||
{
|
||||
int rc = 0;
|
||||
u32 i = 0;
|
||||
@@ -840,7 +840,7 @@ static int msm_vdec_queue_output_internal_buffers(struct msm_vidc_inst *inst)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int msm_vdec_release_input_internal_buffers(struct msm_vidc_inst *inst)
|
||||
int msm_vdec_release_input_internal_buffers(struct msm_vidc_inst *inst)
|
||||
{
|
||||
int rc = 0;
|
||||
u32 i = 0;
|
||||
@@ -1371,30 +1371,6 @@ int msm_vdec_input_port_settings_change(struct msm_vidc_inst *inst)
|
||||
event.u.src_change.changes = V4L2_EVENT_SRC_CH_RESOLUTION;
|
||||
v4l2_event_queue_fh(&inst->event_handler, &event);
|
||||
|
||||
rc = msm_vdec_get_input_internal_buffers(inst);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
rc = msm_vdec_release_input_internal_buffers(inst);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
rc = msm_vdec_create_input_internal_buffers(inst);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
rc = msm_vdec_queue_input_internal_buffers(inst);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
rc = msm_vidc_set_stage(inst, STAGE);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
rc = msm_vidc_set_pipe(inst, PIPE);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
@@ -1489,7 +1465,7 @@ int msm_vdec_streamon_input(struct msm_vidc_inst *inst)
|
||||
if (rc)
|
||||
goto error;
|
||||
|
||||
rc = msm_vidc_process_streamon(inst, INPUT_PORT);
|
||||
rc = msm_vidc_process_streamon_input(inst);
|
||||
if (rc)
|
||||
goto error;
|
||||
|
||||
@@ -1809,7 +1785,7 @@ int msm_vdec_streamon_output(struct msm_vidc_inst *inst)
|
||||
if (rc)
|
||||
goto error;
|
||||
|
||||
rc = msm_vidc_process_streamon(inst, OUTPUT_PORT);
|
||||
rc = msm_vidc_process_streamon_output(inst);
|
||||
if (rc)
|
||||
goto error;
|
||||
|
||||
@@ -2206,6 +2182,27 @@ int msm_vdec_process_cmd(struct msm_vidc_inst *inst, u32 cmd)
|
||||
msm_vidc_allow_dcvs(inst);
|
||||
msm_vidc_power_data_reset(inst);
|
||||
|
||||
/*
|
||||
* client is completing partial port reconfiguration,
|
||||
* hence reallocate input internal buffers before input port
|
||||
* is resumed.
|
||||
*/
|
||||
if (is_sub_state(inst, MSM_VIDC_DRC) &&
|
||||
is_sub_state(inst, MSM_VIDC_DRC_LAST_BUFFER) &&
|
||||
is_sub_state(inst, MSM_VIDC_INPUT_PAUSE)) {
|
||||
rc = msm_vidc_alloc_and_queue_input_internal_buffers(inst);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
rc = msm_vidc_set_stage(inst, STAGE);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
rc = msm_vidc_set_pipe(inst, PIPE);
|
||||
if (rc)
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* allocate and queue extra dpb buffers */
|
||||
rc = msm_vdec_alloc_and_queue_additional_dpb_buffers(inst);
|
||||
if (rc)
|
||||
|
@@ -863,7 +863,7 @@ int msm_venc_streamon_input(struct msm_vidc_inst *inst)
|
||||
if (rc)
|
||||
goto error;
|
||||
|
||||
rc = msm_vidc_process_streamon(inst, INPUT_PORT);
|
||||
rc = msm_vidc_process_streamon_input(inst);
|
||||
if (rc)
|
||||
goto error;
|
||||
|
||||
@@ -1013,7 +1013,7 @@ int msm_venc_streamon_output(struct msm_vidc_inst *inst)
|
||||
if (rc)
|
||||
goto error;
|
||||
|
||||
rc = msm_vidc_process_streamon(inst, OUTPUT_PORT);
|
||||
rc = msm_vidc_process_streamon_output(inst);
|
||||
if (rc)
|
||||
goto error;
|
||||
|
||||
|
@@ -1664,12 +1664,15 @@ bool msm_vidc_allow_start(struct msm_vidc_inst *inst)
|
||||
}
|
||||
|
||||
/* client would call start (resume) to complete DRC/drain sequence */
|
||||
if ((is_sub_state(inst, MSM_VIDC_DRC) &&
|
||||
is_sub_state(inst, MSM_VIDC_DRC_LAST_BUFFER)) ||
|
||||
(is_sub_state(inst, MSM_VIDC_DRAIN) &&
|
||||
is_sub_state(inst, MSM_VIDC_DRAIN_LAST_BUFFER)))
|
||||
allow = true;
|
||||
|
||||
if (inst->state == MSM_VIDC_INPUT_STREAMING ||
|
||||
inst->state == MSM_VIDC_OUTPUT_STREAMING ||
|
||||
inst->state == MSM_VIDC_STREAMING) {
|
||||
if ((is_sub_state(inst, MSM_VIDC_DRC) &&
|
||||
is_sub_state(inst, MSM_VIDC_DRC_LAST_BUFFER)) ||
|
||||
(is_sub_state(inst, MSM_VIDC_DRAIN) &&
|
||||
is_sub_state(inst, MSM_VIDC_DRAIN_LAST_BUFFER)))
|
||||
allow = true;
|
||||
}
|
||||
if (!allow)
|
||||
i_vpr_e(inst, "%s: not allowed in state %s, sub state %s\n",
|
||||
__func__, state_name(inst->state), inst->sub_state_name);
|
||||
@@ -1984,8 +1987,58 @@ int msm_vidc_process_resume(struct msm_vidc_inst *inst)
|
||||
return rc;
|
||||
}
|
||||
|
||||
int msm_vidc_process_streamon(struct msm_vidc_inst *inst,
|
||||
enum msm_vidc_port_type port)
|
||||
int msm_vidc_process_streamon_input(struct msm_vidc_inst *inst)
|
||||
{
|
||||
int rc = 0;
|
||||
enum msm_vidc_sub_state clear_sub_state = MSM_VIDC_SUB_STATE_NONE;
|
||||
enum msm_vidc_sub_state set_sub_state = MSM_VIDC_SUB_STATE_NONE;
|
||||
|
||||
if (!inst) {
|
||||
d_vpr_e("%s: invalid params\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
msm_vidc_scale_power(inst, true);
|
||||
|
||||
rc = venus_hfi_start(inst, INPUT_PORT);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
/* clear input pause substate immediately */
|
||||
if (is_sub_state(inst, MSM_VIDC_INPUT_PAUSE)) {
|
||||
rc = msm_vidc_change_sub_state(inst, MSM_VIDC_INPUT_PAUSE, 0, __func__);
|
||||
if (rc)
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
* if DRC sequence is not completed by the client then PAUSE
|
||||
* firmware input port to avoid firmware raising IPSC again.
|
||||
* When client completes DRC or DRAIN sequences, firmware
|
||||
* input port will be resumed.
|
||||
*/
|
||||
if (is_sub_state(inst, MSM_VIDC_DRC) ||
|
||||
is_sub_state(inst, MSM_VIDC_DRAIN)) {
|
||||
if (!is_sub_state(inst, MSM_VIDC_INPUT_PAUSE)) {
|
||||
rc = venus_hfi_session_pause(inst, INPUT_PORT);
|
||||
if (rc)
|
||||
return rc;
|
||||
set_sub_state = MSM_VIDC_INPUT_PAUSE;
|
||||
}
|
||||
}
|
||||
|
||||
rc = msm_vidc_state_change_streamon(inst, INPUT_PORT);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
rc = msm_vidc_change_sub_state(inst, clear_sub_state, set_sub_state, __func__);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int msm_vidc_process_streamon_output(struct msm_vidc_inst *inst)
|
||||
{
|
||||
int rc = 0;
|
||||
enum msm_vidc_sub_state clear_sub_state = MSM_VIDC_SUB_STATE_NONE;
|
||||
@@ -1997,70 +2050,64 @@ int msm_vidc_process_streamon(struct msm_vidc_inst *inst,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (port == INPUT_META_PORT || port == OUTPUT_META_PORT)
|
||||
return 0;
|
||||
|
||||
msm_vidc_scale_power(inst, true);
|
||||
|
||||
rc = venus_hfi_start(inst, port);
|
||||
/*
|
||||
* client completed drc sequence, reset DRC and
|
||||
* MSM_VIDC_DRC_LAST_BUFFER substates
|
||||
*/
|
||||
if (is_sub_state(inst, MSM_VIDC_DRC) &&
|
||||
is_sub_state(inst, MSM_VIDC_DRC_LAST_BUFFER)) {
|
||||
clear_sub_state = MSM_VIDC_DRC | MSM_VIDC_DRC_LAST_BUFFER;
|
||||
}
|
||||
/*
|
||||
* Client is completing port reconfiguration, hence reallocate
|
||||
* input internal buffers before input port is resumed.
|
||||
* Drc sub-state cannot be checked because DRC sub-state will
|
||||
* not be set during initial port reconfiguration.
|
||||
*/
|
||||
if (is_decode_session(inst) &&
|
||||
is_sub_state(inst, MSM_VIDC_INPUT_PAUSE)) {
|
||||
rc = msm_vidc_alloc_and_queue_input_internal_buffers(inst);
|
||||
if (rc)
|
||||
return rc;
|
||||
rc = msm_vidc_set_stage(inst, STAGE);
|
||||
if (rc)
|
||||
return rc;
|
||||
rc = msm_vidc_set_pipe(inst, PIPE);
|
||||
if (rc)
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
* fw input port is paused due to ipsc. now that client
|
||||
* completed drc sequence, resume fw input port provided
|
||||
* drain is not pending and input port is streaming.
|
||||
*/
|
||||
drain_pending = is_sub_state(inst, MSM_VIDC_DRAIN) &&
|
||||
is_sub_state(inst, MSM_VIDC_DRAIN_LAST_BUFFER);
|
||||
if (!drain_pending && is_state(inst, MSM_VIDC_INPUT_STREAMING)) {
|
||||
if (is_sub_state(inst, MSM_VIDC_INPUT_PAUSE)) {
|
||||
rc = venus_hfi_session_resume(inst, INPUT_PORT,
|
||||
HFI_CMD_SETTINGS_CHANGE);
|
||||
if (rc)
|
||||
return rc;
|
||||
clear_sub_state |= MSM_VIDC_INPUT_PAUSE;
|
||||
}
|
||||
}
|
||||
|
||||
rc = venus_hfi_start(inst, OUTPUT_PORT);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
/* clear input/output pause substate immediately */
|
||||
if (port == INPUT_PORT && is_sub_state(inst, MSM_VIDC_INPUT_PAUSE)) {
|
||||
rc = msm_vidc_change_sub_state(inst, MSM_VIDC_INPUT_PAUSE, 0, __func__);
|
||||
if (rc)
|
||||
return rc;
|
||||
} else if (port == OUTPUT_PORT && is_sub_state(inst, MSM_VIDC_OUTPUT_PAUSE)) {
|
||||
/* clear output pause substate immediately */
|
||||
if (is_sub_state(inst, MSM_VIDC_OUTPUT_PAUSE)) {
|
||||
rc = msm_vidc_change_sub_state(inst, MSM_VIDC_OUTPUT_PAUSE, 0, __func__);
|
||||
if (rc)
|
||||
return rc;
|
||||
}
|
||||
|
||||
if (port == INPUT_PORT) {
|
||||
/*
|
||||
* if DRC sequence is not completed by the client then PAUSE
|
||||
* firmware input port to avoid firmware raising IPSC again.
|
||||
* When client completes DRC or DRAIN sequences, firmware
|
||||
* input port will be resumed.
|
||||
*/
|
||||
if (is_sub_state(inst, MSM_VIDC_DRC) ||
|
||||
is_sub_state(inst, MSM_VIDC_DRAIN)) {
|
||||
if (!is_sub_state(inst, MSM_VIDC_INPUT_PAUSE)) {
|
||||
rc = venus_hfi_session_pause(inst, INPUT_PORT);
|
||||
if (rc)
|
||||
return rc;
|
||||
set_sub_state = MSM_VIDC_INPUT_PAUSE;
|
||||
}
|
||||
}
|
||||
} else if (port == OUTPUT_PORT) {
|
||||
/*
|
||||
* client completed drc sequence, reset DRC and
|
||||
* MSM_VIDC_DRC_LAST_BUFFER substates
|
||||
*/
|
||||
if (is_sub_state(inst, MSM_VIDC_DRC) &&
|
||||
is_sub_state(inst, MSM_VIDC_DRC_LAST_BUFFER)) {
|
||||
clear_sub_state = MSM_VIDC_DRC | MSM_VIDC_DRC_LAST_BUFFER;
|
||||
}
|
||||
/*
|
||||
* fw input port is paused due to ipsc. now that client
|
||||
* completed drc sequence, resume fw input port provided
|
||||
* drain is not pending and input port is streaming.
|
||||
*/
|
||||
drain_pending = is_sub_state(inst, MSM_VIDC_DRAIN) &&
|
||||
is_sub_state(inst, MSM_VIDC_DRAIN_LAST_BUFFER);
|
||||
if (!drain_pending && is_state(inst, MSM_VIDC_INPUT_STREAMING)) {
|
||||
if (is_sub_state(inst, MSM_VIDC_INPUT_PAUSE)) {
|
||||
rc = venus_hfi_session_resume(inst, INPUT_PORT,
|
||||
HFI_CMD_SETTINGS_CHANGE);
|
||||
if (rc)
|
||||
return rc;
|
||||
clear_sub_state |= MSM_VIDC_INPUT_PAUSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
rc = msm_vidc_state_change_streamon(inst, port);
|
||||
rc = msm_vidc_state_change_streamon(inst, OUTPUT_PORT);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
@@ -3587,6 +3634,34 @@ static int msm_vidc_queue_buffer(struct msm_vidc_inst *inst, struct msm_vidc_buf
|
||||
return 0;
|
||||
}
|
||||
|
||||
int msm_vidc_alloc_and_queue_input_internal_buffers(struct msm_vidc_inst *inst)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
if (!inst) {
|
||||
d_vpr_e("%s: invalid params\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
rc = msm_vdec_get_input_internal_buffers(inst);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
rc = msm_vdec_release_input_internal_buffers(inst);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
rc = msm_vdec_create_input_internal_buffers(inst);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
rc = msm_vdec_queue_input_internal_buffers(inst);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int msm_vidc_queue_deferred_buffers(struct msm_vidc_inst *inst, enum msm_vidc_buffer_type buf_type)
|
||||
{
|
||||
struct msm_vidc_buffers *buffers;
|
||||
|
Reference in New Issue
Block a user