diff --git a/driver/vidc/src/msm_vdec.c b/driver/vidc/src/msm_vdec.c index 01747454a5..0bde551cbf 100644 --- a/driver/vidc/src/msm_vdec.c +++ b/driver/vidc/src/msm_vdec.c @@ -1994,14 +1994,6 @@ int msm_vdec_qbuf(struct msm_vidc_inst *inst, struct vb2_buffer *vb2) return -EINVAL; } - if (vb2->type == OUTPUT_MPLANE) { - if (inst->capabilities->cap[DPB_LIST].value) { - rc = msm_vdec_release_nonref_buffers(inst); - if (rc) - return rc; - } - } - if (inst->adjust_priority) { s32 priority = inst->capabilities->cap[PRIORITY].value; @@ -2019,6 +2011,14 @@ int msm_vdec_qbuf(struct msm_vidc_inst *inst, struct vb2_buffer *vb2) if (rc) return rc; + if (vb2->type == OUTPUT_MPLANE) { + if (inst->capabilities->cap[DPB_LIST].value) { + rc = msm_vdec_release_nonref_buffers(inst); + if (rc) + return rc; + } + } + return rc; } diff --git a/driver/vidc/src/msm_vidc_driver.c b/driver/vidc/src/msm_vidc_driver.c index d6c9fbb491..93176ce4dd 100644 --- a/driver/vidc/src/msm_vidc_driver.c +++ b/driver/vidc/src/msm_vidc_driver.c @@ -2501,12 +2501,21 @@ int msm_vidc_process_readonly_buffers(struct msm_vidc_inst *inst, /* * check if read_only buffer is present in read_only list - * if present: add ro flag to buf + * if present: add ro flag to buf provided buffer is not + * pending release */ list_for_each_entry_safe(ro_buf, dummy, &inst->buffers.read_only.list, list) { - if (ro_buf->device_addr == buf->device_addr && - ro_buf->attr & MSM_VIDC_ATTR_READ_ONLY) { + if (ro_buf->device_addr != buf->device_addr) + continue; + if (ro_buf->attr & MSM_VIDC_ATTR_READ_ONLY && + !(ro_buf->attr & MSM_VIDC_ATTR_PENDING_RELEASE)) { + /* add READ_ONLY to the buffer going to the firmware */ buf->attr |= MSM_VIDC_ATTR_READ_ONLY; + /* + * remove READ_ONLY on the read_only list buffer so that + * it will get removed from the read_only list below + */ + ro_buf->attr &= ~MSM_VIDC_ATTR_READ_ONLY; break; } } @@ -2516,13 +2525,21 @@ int msm_vidc_process_readonly_buffers(struct msm_vidc_inst *inst, /* if read only buffer do not remove */ if (ro_buf->attr & MSM_VIDC_ATTR_READ_ONLY) continue; - /* if v4l2 did not ask for unmap/detach then do not remove */ - if (!ro_buf->sg_table || !ro_buf->attach || !ro_buf->dbuf_get) - continue; + print_vidc_buffer(VIDC_LOW, "low ", "ro buf removed", inst, ro_buf); - msm_vidc_dma_buf_unmap_attachment(ro_buf->attach, ro_buf->sg_table); - msm_vidc_dma_buf_detach(ro_buf->dmabuf, ro_buf->attach); - msm_vidc_memory_put_dmabuf(inst, ro_buf->dmabuf); + /* unmap the buffer if driver holds mapping */ + if (ro_buf->sg_table && ro_buf->attach) { + msm_vidc_dma_buf_unmap_attachment(ro_buf->attach, ro_buf->sg_table); + msm_vidc_dma_buf_detach(ro_buf->dmabuf, ro_buf->attach); + ro_buf->dmabuf = NULL; + ro_buf->attach = NULL; + } + if (ro_buf->dbuf_get) { + msm_vidc_memory_put_dmabuf(inst, ro_buf->dmabuf); + ro_buf->dmabuf = NULL; + ro_buf->dbuf_get = 0; + } + list_del_init(&ro_buf->list); msm_memory_pool_free(inst, ro_buf); }