msm: vidc: Add support for decoder STOP command
Decoder STOP command is to signal HW that this is the EOS buffer. HW returns all the pending ETB's and FTB's. One of the FTB_DONE's will have EOS flag back to client. With this, driver don't need to support zero_bytes_used input buffers. CRs-Fixed: 2078801 Signed-off-by: Praneeth Paladugu <ppaladug@codeaurora.org> Change-Id: I44c60db1c98707501b5637eba5d1d81663d6a722
This commit is contained in:
parent
d99718532d
commit
84d22be9dc
4 changed files with 121 additions and 1 deletions
|
@ -1238,7 +1238,7 @@ static inline int vb2_bufq_init(struct msm_vidc_inst *inst,
|
|||
q->ops = msm_venc_get_vb2q_ops();
|
||||
q->mem_ops = &msm_vidc_vb2_mem_ops;
|
||||
q->drv_priv = inst;
|
||||
q->allow_zero_bytesused = 1;
|
||||
q->allow_zero_bytesused = !V4L2_TYPE_IS_OUTPUT(type);
|
||||
return vb2_queue_init(q);
|
||||
}
|
||||
|
||||
|
@ -1356,6 +1356,7 @@ void *msm_vidc_open(int core_id, int session_type)
|
|||
INIT_MSM_VIDC_LIST(&inst->pending_getpropq);
|
||||
INIT_MSM_VIDC_LIST(&inst->outputbufs);
|
||||
INIT_MSM_VIDC_LIST(&inst->registeredbufs);
|
||||
INIT_MSM_VIDC_LIST(&inst->eosbufs);
|
||||
|
||||
kref_init(&inst->kref);
|
||||
|
||||
|
@ -1448,6 +1449,7 @@ fail_mem_client:
|
|||
DEINIT_MSM_VIDC_LIST(&inst->pending_getpropq);
|
||||
DEINIT_MSM_VIDC_LIST(&inst->outputbufs);
|
||||
DEINIT_MSM_VIDC_LIST(&inst->registeredbufs);
|
||||
DEINIT_MSM_VIDC_LIST(&inst->eosbufs);
|
||||
|
||||
kfree(inst);
|
||||
inst = NULL;
|
||||
|
@ -1473,6 +1475,7 @@ static void cleanup_instance(struct msm_vidc_inst *inst)
|
|||
dprintk(VIDC_ERR,
|
||||
"Failed to release scratch buffers\n");
|
||||
}
|
||||
msm_comm_release_eos_buffers(inst);
|
||||
|
||||
if (msm_comm_release_persist_buffers(inst)) {
|
||||
dprintk(VIDC_ERR,
|
||||
|
@ -1516,6 +1519,7 @@ int msm_vidc_destroy(struct msm_vidc_inst *inst)
|
|||
DEINIT_MSM_VIDC_LIST(&inst->pending_getpropq);
|
||||
DEINIT_MSM_VIDC_LIST(&inst->outputbufs);
|
||||
DEINIT_MSM_VIDC_LIST(&inst->registeredbufs);
|
||||
DEINIT_MSM_VIDC_LIST(&inst->eosbufs);
|
||||
|
||||
v4l2_fh_del(&inst->event_handler);
|
||||
v4l2_fh_exit(&inst->event_handler);
|
||||
|
|
|
@ -1829,6 +1829,26 @@ static struct vb2_buffer *get_vb_from_device_addr(struct buf_queue *bufq,
|
|||
return vb;
|
||||
}
|
||||
|
||||
static bool is_eos_buffer(struct msm_vidc_inst *inst, u32 device_addr)
|
||||
{
|
||||
struct eos_buf *temp, *next;
|
||||
bool found = false;
|
||||
|
||||
mutex_lock(&inst->eosbufs.lock);
|
||||
list_for_each_entry_safe(temp, next, &inst->eosbufs.list, list) {
|
||||
if (temp->smem->device_addr == device_addr) {
|
||||
found = true;
|
||||
list_del(&temp->list);
|
||||
msm_comm_smem_free(inst, temp->smem);
|
||||
kfree(temp);
|
||||
break;
|
||||
}
|
||||
}
|
||||
mutex_unlock(&inst->eosbufs.lock);
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
static void handle_ebd(enum hal_command_response cmd, void *data)
|
||||
{
|
||||
struct msm_vidc_cb_data_done *response = data;
|
||||
|
@ -1849,6 +1869,14 @@ static void handle_ebd(enum hal_command_response cmd, void *data)
|
|||
return;
|
||||
}
|
||||
|
||||
empty_buf_done = (struct vidc_hal_ebd *)&response->input_done;
|
||||
/* If this is internal EOS buffer, handle it in driver */
|
||||
if (is_eos_buffer(inst, empty_buf_done->packet_buffer)) {
|
||||
dprintk(VIDC_DBG, "Received EOS buffer %pK\n",
|
||||
(void *)empty_buf_done->packet_buffer);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
vb = get_vb_from_device_addr(&inst->bufq[OUTPUT_PORT],
|
||||
response->input_done.packet_buffer);
|
||||
if (vb) {
|
||||
|
@ -1900,6 +1928,7 @@ static void handle_ebd(enum hal_command_response cmd, void *data)
|
|||
msm_vidc_debugfs_update(inst, MSM_VIDC_DEBUGFS_EVENT_EBD);
|
||||
}
|
||||
|
||||
exit:
|
||||
put_inst(inst);
|
||||
}
|
||||
|
||||
|
@ -3587,6 +3616,66 @@ int msm_vidc_comm_cmd(void *instance, union msm_v4l2_cmd *cmd)
|
|||
"Failed to flush buffers: %d\n", rc);
|
||||
}
|
||||
break;
|
||||
|
||||
case V4L2_DEC_CMD_STOP:
|
||||
{
|
||||
struct vidc_frame_data data = {0};
|
||||
struct hfi_device *hdev;
|
||||
struct eos_buf *binfo;
|
||||
u32 smem_flags = 0;
|
||||
|
||||
get_inst(inst->core, inst);
|
||||
if (inst->session_type != MSM_VIDC_DECODER) {
|
||||
dprintk(VIDC_DBG,
|
||||
"Non-Decoder session. DEC_STOP is not valid\n");
|
||||
rc = -EINVAL;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
binfo = kzalloc(sizeof(*binfo), GFP_KERNEL);
|
||||
if (!binfo) {
|
||||
dprintk(VIDC_ERR, "%s: Out of memory\n", __func__);
|
||||
rc = -ENOMEM;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (inst->flags & VIDC_SECURE)
|
||||
smem_flags |= SMEM_SECURE;
|
||||
|
||||
binfo->smem = msm_comm_smem_alloc(inst,
|
||||
SZ_4K, 1, smem_flags,
|
||||
HAL_BUFFER_INPUT, 0);
|
||||
if (!binfo->smem) {
|
||||
dprintk(VIDC_ERR,
|
||||
"Failed to allocate eos memory\n");
|
||||
goto exit;
|
||||
}
|
||||
|
||||
mutex_lock(&inst->eosbufs.lock);
|
||||
list_add_tail(&binfo->list, &inst->eosbufs.list);
|
||||
mutex_unlock(&inst->eosbufs.lock);
|
||||
|
||||
data.alloc_len = binfo->smem->size;
|
||||
data.device_addr = binfo->smem->device_addr;
|
||||
data.clnt_data = data.device_addr;
|
||||
data.buffer_type = HAL_BUFFER_INPUT;
|
||||
data.filled_len = 0;
|
||||
data.offset = 0;
|
||||
data.flags = HAL_BUFFERFLAG_EOS;
|
||||
data.timestamp = LLONG_MAX;
|
||||
data.extradata_addr = data.device_addr;
|
||||
data.extradata_size = 0;
|
||||
dprintk(VIDC_DBG, "Queueing EOS buffer %pK\n",
|
||||
(void *)data.device_addr);
|
||||
hdev = inst->core->device;
|
||||
|
||||
rc = call_hfi_op(hdev, session_etb, inst->session,
|
||||
&data);
|
||||
exit:
|
||||
put_inst(inst);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
dprintk(VIDC_ERR, "Unknown Command %d\n", which_cmd);
|
||||
rc = -ENOTSUPP;
|
||||
|
@ -4307,6 +4396,26 @@ exit:
|
|||
return rc;
|
||||
}
|
||||
|
||||
void msm_comm_release_eos_buffers(struct msm_vidc_inst *inst)
|
||||
{
|
||||
struct eos_buf *buf, *next;
|
||||
|
||||
if (!inst) {
|
||||
dprintk(VIDC_ERR,
|
||||
"Invalid instance pointer = %pK\n", inst);
|
||||
return;
|
||||
}
|
||||
|
||||
mutex_lock(&inst->eosbufs.lock);
|
||||
list_for_each_entry_safe(buf, next, &inst->eosbufs.list, list) {
|
||||
list_del(&buf->list);
|
||||
msm_comm_smem_free(inst, buf->smem);
|
||||
kfree(buf);
|
||||
}
|
||||
INIT_LIST_HEAD(&inst->eosbufs.list);
|
||||
mutex_unlock(&inst->eosbufs.lock);
|
||||
}
|
||||
|
||||
int msm_comm_release_persist_buffers(struct msm_vidc_inst *inst)
|
||||
{
|
||||
struct msm_smem *handle;
|
||||
|
|
|
@ -60,6 +60,7 @@ int msm_comm_release_scratch_buffers(struct msm_vidc_inst *inst,
|
|||
bool check_for_reuse);
|
||||
int msm_comm_release_persist_buffers(struct msm_vidc_inst *inst);
|
||||
int msm_comm_release_output_buffers(struct msm_vidc_inst *inst);
|
||||
void msm_comm_release_eos_buffers(struct msm_vidc_inst *inst);
|
||||
int msm_comm_force_cleanup(struct msm_vidc_inst *inst);
|
||||
int msm_comm_suspend(int core_id);
|
||||
enum hal_extradata_id msm_comm_get_hal_extradata_index(
|
||||
|
|
|
@ -132,6 +132,11 @@ enum buffer_owner {
|
|||
MAX_OWNER
|
||||
};
|
||||
|
||||
struct eos_buf {
|
||||
struct list_head list;
|
||||
struct msm_smem *smem;
|
||||
};
|
||||
|
||||
struct internal_buf {
|
||||
struct list_head list;
|
||||
enum hal_buffer buffer_type;
|
||||
|
@ -270,6 +275,7 @@ struct msm_vidc_inst {
|
|||
struct msm_vidc_list persistbufs;
|
||||
struct msm_vidc_list pending_getpropq;
|
||||
struct msm_vidc_list outputbufs;
|
||||
struct msm_vidc_list eosbufs;
|
||||
struct msm_vidc_list registeredbufs;
|
||||
struct buffer_requirements buff_req;
|
||||
void *mem_client;
|
||||
|
|
Loading…
Add table
Reference in a new issue