video: driver: fixes for PSC on latest fw
- post input psc, output psc and last flag events to response work handler - fix issue with release and create internal buffers during input psc - clear last flag after session continue Change-Id: Ic0278a09a0f6ee8ffff8840a47cd80c046ecadc4 Signed-off-by: Darshana Patil <darshana@codeaurora.org>
This commit is contained in:

committed by
Gerrit - the friendly Code Review server

parent
2ddc143565
commit
d98075c932
@@ -251,7 +251,7 @@ 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);
|
||||
int msm_vidc_allow_input_psc(struct msm_vidc_inst *inst);
|
||||
bool 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);
|
||||
|
@@ -123,9 +123,9 @@ struct msm_vidc_inst {
|
||||
struct msm_vidc_decode_batch decode_batch;
|
||||
struct msm_vidc_decode_vpp_delay decode_vpp_delay;
|
||||
struct msm_vidc_session_idle session_idle;
|
||||
struct delayed_work input_psc_work;
|
||||
struct workqueue_struct *input_psc_workq;
|
||||
struct list_head input_psc_works; /* list of struct input_psc_work */
|
||||
struct delayed_work response_work;
|
||||
struct workqueue_struct *response_workq;
|
||||
struct list_head response_works; /* list of struct response_work */
|
||||
struct list_head input_ts;
|
||||
struct list_head enc_input_crs;
|
||||
struct list_head decode_bitrate_data;
|
||||
|
@@ -706,10 +706,17 @@ struct msm_vidc_buffers {
|
||||
bool reuse;
|
||||
};
|
||||
|
||||
struct input_psc_work {
|
||||
struct list_head list;
|
||||
void *data;
|
||||
u32 data_size;
|
||||
enum response_work_type {
|
||||
RESP_WORK_INPUT_PSC = 1,
|
||||
RESP_WORK_OUTPUT_PSC,
|
||||
RESP_WORK_LAST_FLAG,
|
||||
};
|
||||
|
||||
struct response_work {
|
||||
struct list_head list;
|
||||
enum response_work_type type;
|
||||
void *data;
|
||||
u32 data_size;
|
||||
};
|
||||
|
||||
struct msm_vidc_ssr {
|
||||
|
@@ -14,8 +14,8 @@ bool is_valid_port(struct msm_vidc_inst *inst, u32 port,
|
||||
const char *func);
|
||||
bool is_valid_hfi_buffer_type(struct msm_vidc_inst *inst,
|
||||
u32 buffer_type, const char *func);
|
||||
void handle_session_input_psc_work_handler(struct work_struct *work);
|
||||
int handle_session_input_psc(struct msm_vidc_inst *inst,
|
||||
struct input_psc_work *psc_work);
|
||||
void handle_session_response_work_handler(struct work_struct *work);
|
||||
int handle_session_response_work(struct msm_vidc_inst *inst,
|
||||
struct response_work *work);
|
||||
|
||||
#endif // __VENUS_HFI_RESPONSE_H__
|
||||
|
@@ -769,7 +769,7 @@ static int msm_vdec_get_input_internal_buffers(struct msm_vidc_inst *inst)
|
||||
inst->buffers.line.min_count,
|
||||
inst->buffers.line.size,
|
||||
inst->buffers.line.reuse);
|
||||
s_vpr_h(inst->sid, "buffer: %d %d %d\n",
|
||||
s_vpr_h(inst->sid, "persist buffer: %d %d %d\n",
|
||||
inst->buffers.persist.min_count,
|
||||
inst->buffers.persist.size,
|
||||
inst->buffers.persist.reuse);
|
||||
@@ -1059,11 +1059,18 @@ static int msm_vdec_session_resume(struct msm_vidc_inst *inst,
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int msm_vdec_update_input_properties(struct msm_vidc_inst *inst)
|
||||
static int msm_vdec_update_properties(struct msm_vidc_inst *inst)
|
||||
{
|
||||
struct msm_vidc_subscription_params subsc_params;
|
||||
struct msm_vidc_core *core;
|
||||
u32 width, height;
|
||||
|
||||
if (!inst || !inst->core) {
|
||||
d_vpr_e("%s: invalid params\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
core = inst->core;
|
||||
|
||||
subsc_params = inst->subcr_params[INPUT_PORT];
|
||||
width = (subsc_params.bitstream_resolution &
|
||||
HFI_BITMASK_BITSTREAM_WIDTH) >> 16;
|
||||
@@ -1081,8 +1088,11 @@ static int msm_vdec_update_input_properties(struct msm_vidc_inst *inst)
|
||||
v4l2_colorformat_to_media(
|
||||
inst->fmts[OUTPUT_PORT].fmt.pix_mp.pixelformat, __func__),
|
||||
height);
|
||||
//inst->fmts[OUTPUT_PORT].fmt.pix_mp.bytesperline =
|
||||
//inst->fmts[OUTPUT_PORT].fmt.pix_mp.width;
|
||||
inst->fmts[OUTPUT_PORT].fmt.pix_mp.plane_fmt[0].bytesperline =
|
||||
inst->fmts[OUTPUT_PORT].fmt.pix_mp.width;
|
||||
inst->fmts[OUTPUT_PORT].fmt.pix_mp.plane_fmt[0].sizeimage =
|
||||
call_session_op(core, buffer_size, inst, MSM_VIDC_BUF_OUTPUT);
|
||||
//inst->buffers.output.size = inst->fmts[OUTPUT_PORT].fmt.pix_mp.plane_fmt[0].sizeimage;
|
||||
|
||||
inst->fmts[OUTPUT_PORT].fmt.pix_mp.colorspace =
|
||||
(subsc_params.color_info & 0xFF0000) >> 16;
|
||||
@@ -1122,7 +1132,7 @@ int msm_vdec_input_port_settings_change(struct msm_vidc_inst *inst)
|
||||
return 0;
|
||||
}
|
||||
|
||||
rc = msm_vdec_update_input_properties(inst);
|
||||
rc = msm_vdec_update_properties(inst);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
@@ -1130,11 +1140,11 @@ 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_release_input_internal_buffers(inst);
|
||||
rc = msm_vdec_get_input_internal_buffers(inst);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
rc = msm_vdec_get_input_internal_buffers(inst);
|
||||
rc = msm_vdec_release_input_internal_buffers(inst);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
@@ -1492,6 +1502,8 @@ int msm_vdec_process_cmd(struct msm_vidc_inst *inst, u32 cmd)
|
||||
0);
|
||||
if (rc)
|
||||
return rc;
|
||||
vb2_clear_last_buffer_dequeued(&inst->vb2q[OUTPUT_META_PORT]);
|
||||
vb2_clear_last_buffer_dequeued(&inst->vb2q[OUTPUT_PORT]);
|
||||
} else {
|
||||
d_vpr_e("%s: unknown cmd %d\n", __func__, cmd);
|
||||
return -EINVAL;
|
||||
|
@@ -256,7 +256,7 @@ int msm_vidc_g_fmt(void *instance, struct v4l2_format *f)
|
||||
if (f->type == INPUT_MPLANE || f->type == OUTPUT_MPLANE)
|
||||
s_vpr_h(inst->sid,
|
||||
"%s: type %d format %#x width %d height %d size %d\n",
|
||||
__func__, f->fmt.pix_mp.pixelformat, f->fmt.pix_mp.width,
|
||||
__func__, f->type, f->fmt.pix_mp.pixelformat, f->fmt.pix_mp.width,
|
||||
f->fmt.pix_mp.height, f->fmt.pix_mp.plane_fmt[0].sizeimage);
|
||||
else if (f->type == INPUT_META_PLANE || f->type == OUTPUT_META_PLANE)
|
||||
s_vpr_h(inst->sid, "%s: meta type %d size %d\n",
|
||||
@@ -683,8 +683,8 @@ void *msm_vidc_open(void *vidc_core, u32 session_type)
|
||||
}
|
||||
s_vpr_i(inst->sid, "Opening video instance: %d\n", session_type);
|
||||
|
||||
inst->input_psc_workq = create_singlethread_workqueue("input_psc_workq");
|
||||
if (!inst->input_psc_workq) {
|
||||
inst->response_workq = create_singlethread_workqueue("response_workq");
|
||||
if (!inst->response_workq) {
|
||||
d_vpr_e("%s: create input_psc_workq failed\n", __func__);
|
||||
goto error;
|
||||
}
|
||||
@@ -697,10 +697,10 @@ void *msm_vidc_open(void *vidc_core, u32 session_type)
|
||||
goto error;
|
||||
}
|
||||
|
||||
INIT_DELAYED_WORK(&inst->input_psc_work,
|
||||
handle_session_input_psc_work_handler);
|
||||
INIT_DELAYED_WORK(&inst->response_work,
|
||||
handle_session_response_work_handler);
|
||||
|
||||
INIT_LIST_HEAD(&inst->input_psc_works);
|
||||
INIT_LIST_HEAD(&inst->response_works);
|
||||
INIT_LIST_HEAD(&inst->buffers.input.list);
|
||||
INIT_LIST_HEAD(&inst->buffers.input_meta.list);
|
||||
INIT_LIST_HEAD(&inst->buffers.output.list);
|
||||
|
@@ -695,18 +695,18 @@ bool msm_vidc_allow_qbuf(struct msm_vidc_inst *inst)
|
||||
}
|
||||
}
|
||||
|
||||
int msm_vidc_allow_input_psc(struct msm_vidc_inst *inst)
|
||||
bool msm_vidc_allow_input_psc(struct msm_vidc_inst *inst)
|
||||
{
|
||||
int rc = 0;
|
||||
bool allow = false;
|
||||
|
||||
if (!inst) {
|
||||
d_vpr_e("%s: invalid params\n", __func__);
|
||||
return -EINVAL;
|
||||
return false;
|
||||
}
|
||||
if (inst->state == MSM_VIDC_START ||
|
||||
inst->state == MSM_VIDC_START_INPUT ||
|
||||
inst->state == MSM_VIDC_DRAIN) {
|
||||
rc = 0;
|
||||
allow = true;
|
||||
} else if (inst->state == MSM_VIDC_DRC ||
|
||||
inst->state == MSM_VIDC_DRC_LAST_FLAG ||
|
||||
inst->state == MSM_VIDC_DRC_DRAIN ||
|
||||
@@ -714,14 +714,14 @@ int msm_vidc_allow_input_psc(struct msm_vidc_inst *inst)
|
||||
inst->state == MSM_VIDC_DRAIN_START_INPUT) {
|
||||
s_vpr_h(inst->sid, "%s: input psc postponed, inst state %s\n",
|
||||
__func__, state_name(inst->state));
|
||||
rc = -EAGAIN;
|
||||
allow = false;
|
||||
} else {
|
||||
s_vpr_e(inst->sid, "%s: input psc in wrong state %s\n",
|
||||
__func__, state_name(inst->state));
|
||||
rc = -EINVAL;
|
||||
allow = false;
|
||||
}
|
||||
|
||||
return rc;
|
||||
return allow;
|
||||
}
|
||||
|
||||
bool msm_vidc_allow_last_flag(struct msm_vidc_inst *inst)
|
||||
@@ -744,7 +744,7 @@ int msm_vidc_state_change_streamon(struct msm_vidc_inst *inst, u32 type)
|
||||
{
|
||||
int rc = 0;
|
||||
enum msm_vidc_inst_state new_state = MSM_VIDC_ERROR;
|
||||
struct input_psc_work *psc_work;
|
||||
struct response_work *resp_work;
|
||||
|
||||
if (!inst || !inst->core) {
|
||||
d_vpr_e("%s: invalid params\n", __func__);
|
||||
@@ -765,25 +765,26 @@ int msm_vidc_state_change_streamon(struct msm_vidc_inst *inst, u32 type)
|
||||
s_vpr_h(inst->sid,
|
||||
"%s: streamon(output) in DRAIN_START_INPUT state\n",
|
||||
__func__);
|
||||
if (list_empty(&inst->input_psc_works)) {
|
||||
new_state = MSM_VIDC_DRAIN;
|
||||
} else {
|
||||
s_vpr_h(inst->sid,
|
||||
"%s: streamon(output) in DRAIN_START_INPUT state, input psc pending\n",
|
||||
__func__);
|
||||
psc_work = list_first_entry(&inst->input_psc_works,
|
||||
struct input_psc_work, list);
|
||||
rc = handle_session_input_psc(inst, psc_work);
|
||||
if (rc) {
|
||||
s_vpr_e(inst->sid,
|
||||
"%s: handle input psc failed\n", __func__);
|
||||
new_state = MSM_VIDC_ERROR;
|
||||
} else {
|
||||
new_state = MSM_VIDC_DRC_DRAIN;
|
||||
new_state = MSM_VIDC_DRAIN;
|
||||
if (!list_empty(&inst->response_works)) {
|
||||
resp_work = list_first_entry(&inst->response_works,
|
||||
struct response_work, list);
|
||||
if (resp_work->type == RESP_WORK_INPUT_PSC) {
|
||||
s_vpr_h(inst->sid,
|
||||
"%s: streamon(output) in DRAIN_START_INPUT state, input psc pending\n",
|
||||
__func__);
|
||||
rc = handle_session_response_work(inst, resp_work);
|
||||
if (rc) {
|
||||
s_vpr_e(inst->sid,
|
||||
"%s: handle input psc failed\n", __func__);
|
||||
new_state = MSM_VIDC_ERROR;
|
||||
} else {
|
||||
new_state = MSM_VIDC_DRC_DRAIN;
|
||||
}
|
||||
list_del(&resp_work->list);
|
||||
kfree(resp_work->data);
|
||||
kfree(resp_work);
|
||||
}
|
||||
list_del(&psc_work->list);
|
||||
kfree(psc_work->data);
|
||||
kfree(psc_work);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -798,7 +799,7 @@ int msm_vidc_state_change_streamoff(struct msm_vidc_inst *inst, u32 type)
|
||||
{
|
||||
int rc = 0;
|
||||
enum msm_vidc_inst_state new_state = MSM_VIDC_ERROR;
|
||||
struct input_psc_work *psc_work, *dummy;
|
||||
struct response_work *resp_work, *dummy;
|
||||
|
||||
if (!inst || !inst->core) {
|
||||
d_vpr_e("%s: invalid params\n", __func__);
|
||||
@@ -819,13 +820,15 @@ int msm_vidc_state_change_streamoff(struct msm_vidc_inst *inst, u32 type)
|
||||
inst->state == MSM_VIDC_DRAIN_START_INPUT) {
|
||||
new_state = MSM_VIDC_START_OUTPUT;
|
||||
/* discard pending port settings change if any */
|
||||
list_for_each_entry_safe(psc_work, dummy,
|
||||
&inst->input_psc_works, list) {
|
||||
s_vpr_h(inst->sid,
|
||||
"%s: discard pending input psc\n", __func__);
|
||||
list_del(&psc_work->list);
|
||||
kfree(psc_work->data);
|
||||
kfree(psc_work);
|
||||
list_for_each_entry_safe(resp_work, dummy,
|
||||
&inst->response_works, list) {
|
||||
if (resp_work->type == RESP_WORK_INPUT_PSC) {
|
||||
s_vpr_h(inst->sid,
|
||||
"%s: discard pending input psc\n", __func__);
|
||||
list_del(&resp_work->list);
|
||||
kfree(resp_work->data);
|
||||
kfree(resp_work);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (type == OUTPUT_MPLANE) {
|
||||
@@ -884,7 +887,7 @@ int msm_vidc_state_change_start(struct msm_vidc_inst *inst)
|
||||
{
|
||||
int rc = 0;
|
||||
enum msm_vidc_inst_state new_state = MSM_VIDC_ERROR;
|
||||
struct input_psc_work *psc_work;
|
||||
struct response_work *resp_work;
|
||||
|
||||
if (!inst || !inst->core) {
|
||||
d_vpr_e("%s: invalid params\n", __func__);
|
||||
@@ -893,45 +896,47 @@ int msm_vidc_state_change_start(struct msm_vidc_inst *inst)
|
||||
|
||||
if (inst->state == MSM_VIDC_DRAIN_LAST_FLAG ||
|
||||
inst->state == MSM_VIDC_DRC_LAST_FLAG) {
|
||||
if (list_empty(&inst->input_psc_works)) {
|
||||
new_state = MSM_VIDC_START;
|
||||
} else {
|
||||
s_vpr_h(inst->sid,
|
||||
"%s: start in DRC(DRAIN)_LAST_FLAG state, input psc pending\n",
|
||||
__func__);
|
||||
psc_work = list_first_entry(&inst->input_psc_works,
|
||||
struct input_psc_work, list);
|
||||
rc = handle_session_input_psc(inst, psc_work);
|
||||
if (rc) {
|
||||
s_vpr_e(inst->sid,
|
||||
"%s: handle input psc failed\n", __func__);
|
||||
new_state = MSM_VIDC_ERROR;
|
||||
} else {
|
||||
new_state = MSM_VIDC_DRC;
|
||||
if (!list_empty(&inst->response_works)) {
|
||||
resp_work = list_first_entry(&inst->response_works,
|
||||
struct response_work, list);
|
||||
if (resp_work->type == RESP_WORK_INPUT_PSC) {
|
||||
s_vpr_h(inst->sid,
|
||||
"%s: start in DRC(DRAIN)_LAST_FLAG state, input psc pending\n",
|
||||
__func__);
|
||||
rc = handle_session_response_work(inst, resp_work);
|
||||
if (rc) {
|
||||
s_vpr_e(inst->sid,
|
||||
"%s: handle input psc failed\n", __func__);
|
||||
new_state = MSM_VIDC_ERROR;
|
||||
} else {
|
||||
new_state = MSM_VIDC_DRC;
|
||||
}
|
||||
list_del(&resp_work->list);
|
||||
kfree(resp_work->data);
|
||||
kfree(resp_work);
|
||||
}
|
||||
list_del(&psc_work->list);
|
||||
kfree(psc_work->data);
|
||||
kfree(psc_work);
|
||||
}
|
||||
} else if (inst->state == MSM_VIDC_DRC_DRAIN_LAST_FLAG) {
|
||||
if (list_empty(&inst->input_psc_works)) {
|
||||
new_state = MSM_VIDC_DRAIN;
|
||||
} else {
|
||||
s_vpr_h(inst->sid,
|
||||
"%s: start in DRC_DRAIN_LAST_FLAG state, input psc pending\n");
|
||||
psc_work = list_first_entry(&inst->input_psc_works,
|
||||
struct input_psc_work, list);
|
||||
rc = handle_session_input_psc(inst, psc_work);
|
||||
if (rc) {
|
||||
s_vpr_e(inst->sid,
|
||||
"%s: handle input psc failed\n", __func__);
|
||||
new_state = MSM_VIDC_ERROR;
|
||||
} else {
|
||||
new_state = MSM_VIDC_DRC_DRAIN;
|
||||
if (!list_empty(&inst->response_works)) {
|
||||
resp_work = list_first_entry(&inst->response_works,
|
||||
struct response_work, list);
|
||||
if (resp_work->type == RESP_WORK_INPUT_PSC) {
|
||||
s_vpr_h(inst->sid,
|
||||
"%s: start in DRC_DRAIN_LAST_FLAG state, input psc pending\n");
|
||||
rc = handle_session_response_work(inst, resp_work);
|
||||
if (rc) {
|
||||
s_vpr_e(inst->sid,
|
||||
"%s: handle input psc failed\n", __func__);
|
||||
new_state = MSM_VIDC_ERROR;
|
||||
} else {
|
||||
new_state = MSM_VIDC_DRC_DRAIN;
|
||||
}
|
||||
list_del(&resp_work->list);
|
||||
kfree(resp_work->data);
|
||||
kfree(resp_work);
|
||||
}
|
||||
list_del(&psc_work->list);
|
||||
kfree(psc_work->data);
|
||||
kfree(psc_work);
|
||||
}
|
||||
} else {
|
||||
s_vpr_e(inst->sid, "%s: wrong state %s\n",
|
||||
@@ -2480,8 +2485,8 @@ static void msm_vidc_close_helper(struct kref *kref)
|
||||
else if (is_encode_session(inst))
|
||||
msm_venc_inst_deinit(inst);
|
||||
kfree(inst->capabilities);
|
||||
if (inst->input_psc_workq)
|
||||
destroy_workqueue(inst->input_psc_workq);
|
||||
if (inst->response_workq)
|
||||
destroy_workqueue(inst->response_workq);
|
||||
}
|
||||
|
||||
struct msm_vidc_inst *get_inst_ref(struct msm_vidc_core *core,
|
||||
|
@@ -147,6 +147,25 @@ int validate_packet(u8 *response_pkt, u8 *core_resp_pkt,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool check_last_flag(struct msm_vidc_inst *inst,
|
||||
struct hfi_packet *pkt)
|
||||
{
|
||||
struct hfi_buffer *buffer;
|
||||
|
||||
if (!inst || !pkt) {
|
||||
d_vpr_e("%s: invalid params %d\n", __func__);
|
||||
return false;
|
||||
}
|
||||
|
||||
buffer = (struct hfi_buffer *)((u8 *)pkt + sizeof(struct hfi_packet));
|
||||
if (buffer->flags & HFI_BUF_FW_FLAG_LAST) {
|
||||
s_vpr_h(inst->sid, "%s: received last flag on FBD, index: %d\n",
|
||||
__func__, buffer->index);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static int handle_session_info(struct msm_vidc_inst *inst,
|
||||
struct hfi_packet *pkt)
|
||||
{
|
||||
@@ -432,12 +451,8 @@ static int handle_output_buffer(struct msm_vidc_inst *inst,
|
||||
/*if (buffer->flags & HFI_BUF_FW_FLAG_SUBFRAME)
|
||||
buf->flags |= MSM_VIDC_BUF_FLAG_SUBFRAME;*/
|
||||
|
||||
if (buffer->flags & HFI_BUF_FW_FLAG_LAST) {
|
||||
if (msm_vidc_allow_last_flag(inst)) {
|
||||
buf->flags |= MSM_VIDC_BUF_FLAG_LAST;
|
||||
msm_vidc_state_change_last_flag(inst);
|
||||
}
|
||||
}
|
||||
if (buffer->flags & HFI_BUF_FW_FLAG_LAST)
|
||||
buf->flags |= MSM_VIDC_BUF_FLAG_LAST;
|
||||
print_vidc_buffer(VIDC_HIGH, "FBD", inst, buf);
|
||||
|
||||
return rc;
|
||||
@@ -970,8 +985,8 @@ exit:
|
||||
return rc;
|
||||
}
|
||||
|
||||
int handle_session_input_psc(struct msm_vidc_inst *inst,
|
||||
struct input_psc_work *psc_work)
|
||||
int handle_session_response_work(struct msm_vidc_inst *inst,
|
||||
struct response_work *resp_work)
|
||||
{
|
||||
int rc = 0;
|
||||
struct hfi_header *hdr = NULL;
|
||||
@@ -981,12 +996,12 @@ int handle_session_input_psc(struct msm_vidc_inst *inst,
|
||||
u32 hfi_port = 0;
|
||||
int i;
|
||||
|
||||
if (!inst || !psc_work) {
|
||||
if (!inst || !resp_work) {
|
||||
d_vpr_e("%s: invalid params\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
hdr = (struct hfi_header *)psc_work->data;
|
||||
hdr = (struct hfi_header *)resp_work->data;
|
||||
if (!hdr) {
|
||||
d_vpr_e("%s: invalid params\n", __func__);
|
||||
return -EINVAL;
|
||||
@@ -998,8 +1013,8 @@ int handle_session_input_psc(struct msm_vidc_inst *inst,
|
||||
temp_pkt = pkt;
|
||||
|
||||
for (i = 0; i < hdr->num_packets; i++) {
|
||||
if (validate_packet(pkt, psc_work->data,
|
||||
psc_work->data_size, __func__)) {
|
||||
if (validate_packet(pkt, resp_work->data,
|
||||
resp_work->data_size, __func__)) {
|
||||
rc = -EINVAL;
|
||||
goto exit;
|
||||
}
|
||||
@@ -1034,23 +1049,44 @@ int handle_session_input_psc(struct msm_vidc_inst *inst,
|
||||
pkt += packet->size;
|
||||
}
|
||||
|
||||
print_psc_properties(VIDC_HIGH, "INPUT_PSC", inst,
|
||||
inst->subcr_params[INPUT_PORT]);
|
||||
rc = msm_vdec_input_port_settings_change(inst);
|
||||
if (rc)
|
||||
goto exit;
|
||||
|
||||
if (hfi_cmd_type == HFI_CMD_BUFFER) {
|
||||
rc = handle_dequeue_buffers(inst);
|
||||
if (rc)
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (hfi_cmd_type == HFI_CMD_SETTINGS_CHANGE) {
|
||||
if (hfi_port == HFI_PORT_RAW) {
|
||||
print_psc_properties(VIDC_HIGH, "OUTPUT_PSC", inst,
|
||||
inst->subcr_params[OUTPUT_PORT]);
|
||||
rc = msm_vdec_output_port_settings_change(inst);
|
||||
if (rc)
|
||||
goto exit;
|
||||
} else if (hfi_port == HFI_PORT_BITSTREAM) {
|
||||
print_psc_properties(VIDC_HIGH, "INPUT_PSC", inst,
|
||||
inst->subcr_params[INPUT_PORT]);
|
||||
rc = msm_vdec_input_port_settings_change(inst);
|
||||
if (rc)
|
||||
goto exit;
|
||||
} else {
|
||||
s_vpr_e(inst->sid, "%s: invalid port type: %#x\n",
|
||||
__func__, hfi_port);
|
||||
}
|
||||
}
|
||||
|
||||
exit:
|
||||
return rc;
|
||||
}
|
||||
|
||||
void handle_session_input_psc_work_handler(struct work_struct *work)
|
||||
void handle_session_response_work_handler(struct work_struct *work)
|
||||
{
|
||||
int rc = 0;
|
||||
bool allow = false;
|
||||
struct msm_vidc_inst *inst;
|
||||
struct input_psc_work *psc_work, *dummy = NULL;
|
||||
struct response_work *resp_work, *dummy = NULL;
|
||||
|
||||
inst = container_of(work, struct msm_vidc_inst, input_psc_work.work);
|
||||
inst = container_of(work, struct msm_vidc_inst, response_work.work);
|
||||
inst = get_inst_ref(g_core, inst);
|
||||
if (!inst) {
|
||||
d_vpr_e("%s: invalid params\n", __func__);
|
||||
@@ -1058,26 +1094,74 @@ void handle_session_input_psc_work_handler(struct work_struct *work)
|
||||
}
|
||||
|
||||
mutex_lock(&inst->lock);
|
||||
list_for_each_entry_safe(psc_work, dummy, &inst->input_psc_works, list) {
|
||||
rc = msm_vidc_allow_input_psc(inst);
|
||||
if (!rc) {
|
||||
rc = handle_session_input_psc(inst, psc_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);
|
||||
|
||||
/* 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__);
|
||||
break;
|
||||
}
|
||||
rc = handle_session_response_work(inst, resp_work);
|
||||
if (!rc)
|
||||
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__);
|
||||
break;
|
||||
default:
|
||||
d_vpr_e("%s: invalid response work type %d\n", __func__,
|
||||
resp_work->type);
|
||||
break;
|
||||
}
|
||||
list_del(&psc_work->list);
|
||||
kfree(psc_work->data);
|
||||
kfree(psc_work);
|
||||
list_del(&resp_work->list);
|
||||
kfree(resp_work->data);
|
||||
kfree(resp_work);
|
||||
}
|
||||
mutex_unlock(&inst->lock);
|
||||
|
||||
put_inst(inst);
|
||||
}
|
||||
|
||||
static int queue_response_work(struct msm_vidc_inst *inst,
|
||||
enum response_work_type type, void *hdr, u32 hdr_size)
|
||||
{
|
||||
struct response_work *work;
|
||||
|
||||
work = kzalloc(sizeof(struct response_work), GFP_KERNEL);
|
||||
INIT_LIST_HEAD(&work->list);
|
||||
work->type = type;
|
||||
work->data_size = hdr_size;
|
||||
work->data = kzalloc(hdr_size, GFP_KERNEL);
|
||||
if (!work->data)
|
||||
return -ENOMEM;
|
||||
memcpy(work->data, hdr, hdr_size);
|
||||
list_add_tail(&work->list, &inst->response_works);
|
||||
queue_delayed_work(inst->response_workq,
|
||||
&inst->response_work, msecs_to_jiffies(0));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int handle_session_response(struct msm_vidc_core *core,
|
||||
struct hfi_header *hdr)
|
||||
{
|
||||
@@ -1109,29 +1193,19 @@ static int handle_session_response(struct msm_vidc_core *core,
|
||||
packet = (struct hfi_packet *)pkt;
|
||||
if (packet->type > HFI_CMD_BEGIN &&
|
||||
packet->type < HFI_CMD_END) {
|
||||
if (packet->type == HFI_CMD_SETTINGS_CHANGE &&
|
||||
packet->port == HFI_PORT_BITSTREAM) {
|
||||
struct input_psc_work *work;
|
||||
|
||||
work = kzalloc(sizeof(struct input_psc_work), GFP_KERNEL);
|
||||
INIT_LIST_HEAD(&work->list);
|
||||
work->data_size = hdr->size;
|
||||
work->data = kzalloc(hdr->size, GFP_KERNEL);
|
||||
if (!work->data) {
|
||||
rc= -ENOMEM;
|
||||
if (packet->type == HFI_CMD_SETTINGS_CHANGE) {
|
||||
if (packet->port == HFI_PORT_BITSTREAM)
|
||||
rc = queue_response_work(inst, RESP_WORK_INPUT_PSC,
|
||||
(void *)hdr, hdr->size);
|
||||
else if (packet->port == HFI_PORT_RAW)
|
||||
rc = queue_response_work(inst, RESP_WORK_OUTPUT_PSC,
|
||||
(void *)hdr, hdr->size);
|
||||
goto exit;
|
||||
}
|
||||
memcpy(work->data, (void *)hdr, hdr->size);
|
||||
list_add_tail(&work->list, &inst->input_psc_works);
|
||||
queue_delayed_work(inst->input_psc_workq,
|
||||
&inst->input_psc_work, msecs_to_jiffies(0));
|
||||
goto exit;
|
||||
}
|
||||
if (hfi_cmd_type == HFI_CMD_SETTINGS_CHANGE) {
|
||||
s_vpr_e(inst->sid,
|
||||
"%s: invalid packet type %d in port settings change\n",
|
||||
__func__, packet->type);
|
||||
rc = -EINVAL;
|
||||
} else if (packet->type == HFI_CMD_BUFFER &&
|
||||
packet->port == HFI_PORT_RAW &&
|
||||
check_last_flag(inst, packet)) {
|
||||
rc = queue_response_work(inst, RESP_WORK_LAST_FLAG,
|
||||
(void *)hdr, hdr->size);
|
||||
goto exit;
|
||||
}
|
||||
hfi_cmd_type = packet->type;
|
||||
@@ -1161,19 +1235,6 @@ static int handle_session_response(struct msm_vidc_core *core,
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (hfi_cmd_type == HFI_CMD_SETTINGS_CHANGE) {
|
||||
if (hfi_port == HFI_PORT_RAW) {
|
||||
print_psc_properties(VIDC_HIGH, "OUTPUT_PSC", inst,
|
||||
inst->subcr_params[OUTPUT_PORT]);
|
||||
rc = msm_vdec_output_port_settings_change(inst);
|
||||
if (rc)
|
||||
goto exit;
|
||||
} else {
|
||||
s_vpr_e(inst->sid, "%s: invalid port type: %#x\n",
|
||||
__func__, hfi_port);
|
||||
}
|
||||
}
|
||||
|
||||
exit:
|
||||
mutex_unlock(&inst->lock);
|
||||
put_inst(inst);
|
||||
|
Reference in New Issue
Block a user