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:
Darshana Patil
2021-01-05 16:08:54 -08:00
committed by Gerrit - the friendly Code Review server
parent 2ddc143565
commit d98075c932
8 changed files with 241 additions and 156 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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