mirror of
https://github.com/rd-stuffs/msm-4.14.git
synced 2025-02-20 11:45:48 +08:00
Merge "msm: vidc: access vb2 buffer under vb2_queue lock"
This commit is contained in:
commit
26f2554b44
@ -2322,9 +2322,13 @@ struct vb2_buffer *msm_comm_get_vb_using_vidc_buffer(
|
||||
return NULL;
|
||||
}
|
||||
|
||||
q = &inst->bufq[port].vb2_bufq;
|
||||
mutex_lock(&inst->bufq[port].lock);
|
||||
found = false;
|
||||
q = &inst->bufq[port].vb2_bufq;
|
||||
if (!q->streaming) {
|
||||
dprintk(VIDC_ERR, "port %d is not streaming", port);
|
||||
goto unlock;
|
||||
}
|
||||
list_for_each_entry(vb, &q->queued_list, queued_entry) {
|
||||
if (vb->state != VB2_BUF_STATE_ACTIVE)
|
||||
continue;
|
||||
@ -2333,6 +2337,7 @@ struct vb2_buffer *msm_comm_get_vb_using_vidc_buffer(
|
||||
break;
|
||||
}
|
||||
}
|
||||
unlock:
|
||||
mutex_unlock(&inst->bufq[port].lock);
|
||||
if (!found) {
|
||||
print_vidc_buffer(VIDC_ERR, "vb2 not found for", inst, mbuf);
|
||||
@ -2343,28 +2348,52 @@ struct vb2_buffer *msm_comm_get_vb_using_vidc_buffer(
|
||||
}
|
||||
|
||||
int msm_comm_vb2_buffer_done(struct msm_vidc_inst *inst,
|
||||
struct vb2_buffer *vb)
|
||||
struct msm_vidc_buffer *mbuf)
|
||||
{
|
||||
u32 port;
|
||||
struct vb2_buffer *vb2;
|
||||
struct vb2_v4l2_buffer *vbuf;
|
||||
u32 i, port;
|
||||
|
||||
if (!inst || !vb) {
|
||||
if (!inst || !mbuf) {
|
||||
dprintk(VIDC_ERR, "%s: invalid params %pK %pK\n",
|
||||
__func__, inst, vb);
|
||||
__func__, inst, mbuf);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (vb->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
|
||||
if (mbuf->vvb.vb2_buf.type ==
|
||||
V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
|
||||
port = CAPTURE_PORT;
|
||||
} else if (vb->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
|
||||
else if (mbuf->vvb.vb2_buf.type ==
|
||||
V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
|
||||
port = OUTPUT_PORT;
|
||||
} else {
|
||||
dprintk(VIDC_ERR, "%s: invalid type %d\n",
|
||||
__func__, vb->type);
|
||||
else
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
vb2 = msm_comm_get_vb_using_vidc_buffer(inst, mbuf);
|
||||
if (!vb2)
|
||||
return -EINVAL;
|
||||
|
||||
/*
|
||||
* access vb2 buffer under q->lock and if streaming only to
|
||||
* ensure the buffer was not free'd by vb2 framework while
|
||||
* we are accessing it here.
|
||||
*/
|
||||
mutex_lock(&inst->bufq[port].lock);
|
||||
vb2_buffer_done(vb, VB2_BUF_STATE_DONE);
|
||||
if (inst->bufq[port].vb2_bufq.streaming) {
|
||||
vbuf = to_vb2_v4l2_buffer(vb2);
|
||||
vbuf->flags = mbuf->vvb.flags;
|
||||
vb2->timestamp = mbuf->vvb.vb2_buf.timestamp;
|
||||
for (i = 0; i < mbuf->vvb.vb2_buf.num_planes; i++) {
|
||||
vb2->planes[i].bytesused =
|
||||
mbuf->vvb.vb2_buf.planes[i].bytesused;
|
||||
vb2->planes[i].data_offset =
|
||||
mbuf->vvb.vb2_buf.planes[i].data_offset;
|
||||
}
|
||||
vb2_buffer_done(vb2, VB2_BUF_STATE_DONE);
|
||||
} else {
|
||||
dprintk(VIDC_ERR, "%s: port %d is not streaming\n",
|
||||
__func__, port);
|
||||
}
|
||||
mutex_unlock(&inst->bufq[port].lock);
|
||||
|
||||
return 0;
|
||||
@ -2438,12 +2467,11 @@ static void handle_ebd(enum hal_command_response cmd, void *data)
|
||||
{
|
||||
struct msm_vidc_cb_data_done *response = data;
|
||||
struct msm_vidc_buffer *mbuf;
|
||||
struct vb2_buffer *vb, *vb2;
|
||||
struct vb2_buffer *vb;
|
||||
struct msm_vidc_inst *inst;
|
||||
struct vidc_hal_ebd *empty_buf_done;
|
||||
struct vb2_v4l2_buffer *vbuf;
|
||||
u32 planes[VIDEO_MAX_PLANES] = {0};
|
||||
u32 extra_idx = 0, i;
|
||||
u32 extra_idx = 0;
|
||||
|
||||
if (!response) {
|
||||
dprintk(VIDC_ERR, "Invalid response from vidc_hal\n");
|
||||
@ -2476,15 +2504,6 @@ static void handle_ebd(enum hal_command_response cmd, void *data)
|
||||
__func__, planes[0], planes[1]);
|
||||
goto exit;
|
||||
}
|
||||
vb2 = msm_comm_get_vb_using_vidc_buffer(inst, mbuf);
|
||||
|
||||
/*
|
||||
* take registeredbufs.lock to update mbuf & vb2 variables together
|
||||
* so that both are in sync else if mbuf and vb2 variables are not
|
||||
* in sync msm_comm_compare_vb2_planes() returns false for the
|
||||
* right buffer due to data_offset field mismatch.
|
||||
*/
|
||||
mutex_lock(&inst->registeredbufs.lock);
|
||||
vb = &mbuf->vvb.vb2_buf;
|
||||
|
||||
vb->planes[0].bytesused = response->input_done.filled_len;
|
||||
@ -2510,18 +2529,6 @@ static void handle_ebd(enum hal_command_response cmd, void *data)
|
||||
if (extra_idx && extra_idx < VIDEO_MAX_PLANES)
|
||||
vb->planes[extra_idx].bytesused = vb->planes[extra_idx].length;
|
||||
|
||||
if (vb2) {
|
||||
vbuf = to_vb2_v4l2_buffer(vb2);
|
||||
vbuf->flags |= mbuf->vvb.flags;
|
||||
for (i = 0; i < mbuf->vvb.vb2_buf.num_planes; i++) {
|
||||
vb2->planes[i].bytesused =
|
||||
mbuf->vvb.vb2_buf.planes[i].bytesused;
|
||||
vb2->planes[i].data_offset =
|
||||
mbuf->vvb.vb2_buf.planes[i].data_offset;
|
||||
}
|
||||
}
|
||||
mutex_unlock(&inst->registeredbufs.lock);
|
||||
|
||||
update_recon_stats(inst, &empty_buf_done->recon_stats);
|
||||
msm_vidc_clear_freq_entry(inst, mbuf->smem[0].device_addr);
|
||||
/*
|
||||
@ -2535,7 +2542,7 @@ static void handle_ebd(enum hal_command_response cmd, void *data)
|
||||
* in put_buffer.
|
||||
*/
|
||||
msm_comm_put_vidc_buffer(inst, mbuf);
|
||||
msm_comm_vb2_buffer_done(inst, vb2);
|
||||
msm_comm_vb2_buffer_done(inst, mbuf);
|
||||
msm_vidc_debugfs_update(inst, MSM_VIDC_DEBUGFS_EVENT_EBD);
|
||||
kref_put_mbuf(mbuf);
|
||||
exit:
|
||||
@ -2589,13 +2596,12 @@ static void handle_fbd(enum hal_command_response cmd, void *data)
|
||||
struct msm_vidc_cb_data_done *response = data;
|
||||
struct msm_vidc_buffer *mbuf;
|
||||
struct msm_vidc_inst *inst;
|
||||
struct vb2_buffer *vb, *vb2;
|
||||
struct vb2_buffer *vb;
|
||||
struct vidc_hal_fbd *fill_buf_done;
|
||||
struct vb2_v4l2_buffer *vbuf;
|
||||
enum hal_buffer buffer_type;
|
||||
u64 time_usec = 0;
|
||||
u32 planes[VIDEO_MAX_PLANES] = {0};
|
||||
u32 extra_idx, i;
|
||||
u32 extra_idx;
|
||||
|
||||
if (!response) {
|
||||
dprintk(VIDC_ERR, "Invalid response from vidc_hal\n");
|
||||
@ -2623,7 +2629,6 @@ static void handle_fbd(enum hal_command_response cmd, void *data)
|
||||
__func__, planes[0], planes[1]);
|
||||
goto exit;
|
||||
}
|
||||
vb2 = msm_comm_get_vb_using_vidc_buffer(inst, mbuf);
|
||||
} else {
|
||||
if (handle_multi_stream_buffers(inst,
|
||||
fill_buf_done->packet_buffer1))
|
||||
@ -2632,14 +2637,6 @@ static void handle_fbd(enum hal_command_response cmd, void *data)
|
||||
&fill_buf_done->packet_buffer1);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/*
|
||||
* take registeredbufs.lock to update mbuf & vb2 variables together
|
||||
* so that both are in sync else if mbuf and vb2 variables are not
|
||||
* in sync msm_comm_compare_vb2_planes() returns false for the
|
||||
* right buffer due to data_offset field mismatch.
|
||||
*/
|
||||
mutex_lock(&inst->registeredbufs.lock);
|
||||
vb = &mbuf->vvb.vb2_buf;
|
||||
|
||||
if (fill_buf_done->flags1 & HAL_BUFFERFLAG_DROP_FRAME)
|
||||
@ -2698,19 +2695,6 @@ static void handle_fbd(enum hal_command_response cmd, void *data)
|
||||
break;
|
||||
}
|
||||
|
||||
if (vb2) {
|
||||
vbuf = to_vb2_v4l2_buffer(vb2);
|
||||
vbuf->flags = mbuf->vvb.flags;
|
||||
vb2->timestamp = mbuf->vvb.vb2_buf.timestamp;
|
||||
for (i = 0; i < mbuf->vvb.vb2_buf.num_planes; i++) {
|
||||
vb2->planes[i].bytesused =
|
||||
mbuf->vvb.vb2_buf.planes[i].bytesused;
|
||||
vb2->planes[i].data_offset =
|
||||
mbuf->vvb.vb2_buf.planes[i].data_offset;
|
||||
}
|
||||
}
|
||||
mutex_unlock(&inst->registeredbufs.lock);
|
||||
|
||||
/*
|
||||
* dma cache operations need to be performed before dma_unmap
|
||||
* which is done inside msm_comm_put_vidc_buffer()
|
||||
@ -2722,7 +2706,7 @@ static void handle_fbd(enum hal_command_response cmd, void *data)
|
||||
* in put_buffer.
|
||||
*/
|
||||
msm_comm_put_vidc_buffer(inst, mbuf);
|
||||
msm_comm_vb2_buffer_done(inst, vb2);
|
||||
msm_comm_vb2_buffer_done(inst, mbuf);
|
||||
msm_vidc_debugfs_update(inst, MSM_VIDC_DEBUGFS_EVENT_FBD);
|
||||
kref_put_mbuf(mbuf);
|
||||
|
||||
@ -6100,7 +6084,6 @@ bool msm_comm_compare_vb2_plane(struct msm_vidc_inst *inst,
|
||||
|
||||
vb = &mbuf->vvb.vb2_buf;
|
||||
if (vb->planes[i].m.fd == vb2->planes[i].m.fd &&
|
||||
vb->planes[i].data_offset == vb2->planes[i].data_offset &&
|
||||
vb->planes[i].length == vb2->planes[i].length) {
|
||||
return true;
|
||||
}
|
||||
@ -6232,6 +6215,7 @@ int msm_comm_flush_vidc_buffer(struct msm_vidc_inst *inst,
|
||||
{
|
||||
int rc;
|
||||
struct vb2_buffer *vb;
|
||||
u32 port;
|
||||
|
||||
if (!inst || !mbuf) {
|
||||
dprintk(VIDC_ERR, "%s: invalid params %pK %pK\n",
|
||||
@ -6246,11 +6230,24 @@ int msm_comm_flush_vidc_buffer(struct msm_vidc_inst *inst,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
vb->planes[0].bytesused = 0;
|
||||
rc = msm_comm_vb2_buffer_done(inst, vb);
|
||||
if (rc)
|
||||
print_vidc_buffer(VIDC_ERR,
|
||||
"vb2_buffer_done failed for", inst, mbuf);
|
||||
if (mbuf->vvb.vb2_buf.type ==
|
||||
V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
|
||||
port = CAPTURE_PORT;
|
||||
else if (mbuf->vvb.vb2_buf.type ==
|
||||
V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
|
||||
port = OUTPUT_PORT;
|
||||
else
|
||||
return -EINVAL;
|
||||
|
||||
mutex_lock(&inst->bufq[port].lock);
|
||||
if (inst->bufq[port].vb2_bufq.streaming) {
|
||||
vb->planes[0].bytesused = 0;
|
||||
vb2_buffer_done(vb, VB2_BUF_STATE_DONE);
|
||||
} else {
|
||||
dprintk(VIDC_ERR, "%s: port %d is not streaming\n",
|
||||
__func__, port);
|
||||
}
|
||||
mutex_unlock(&inst->bufq[port].lock);
|
||||
|
||||
return rc;
|
||||
}
|
||||
@ -6415,23 +6412,24 @@ struct msm_vidc_buffer *msm_comm_get_vidc_buffer(struct msm_vidc_inst *inst,
|
||||
}
|
||||
|
||||
mutex_lock(&inst->registeredbufs.lock);
|
||||
if (inst->session_type == MSM_VIDC_DECODER) {
|
||||
/*
|
||||
* for encoder input, client may queue the same buffer with different
|
||||
* fd before driver returned old buffer to the client. This buffer
|
||||
* should be treated as new buffer Search the list with fd so that
|
||||
* it will be treated as new msm_vidc_buffer.
|
||||
*/
|
||||
if (is_encode_session(inst) && vb2->type ==
|
||||
V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
|
||||
list_for_each_entry(mbuf, &inst->registeredbufs.list, list) {
|
||||
if (msm_comm_compare_dma_planes(inst, mbuf,
|
||||
dma_planes)) {
|
||||
if (msm_comm_compare_vb2_planes(inst, mbuf, vb2)) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
* for encoder, client may queue the same buffer with different
|
||||
* fd before driver returned old buffer to the client. This
|
||||
* buffer should be treated as new buffer. Search the list with
|
||||
* fd so that it will be treated as new msm_vidc_buffer.
|
||||
*/
|
||||
list_for_each_entry(mbuf, &inst->registeredbufs.list, list) {
|
||||
if (msm_comm_compare_vb2_planes(inst, mbuf, vb2)) {
|
||||
if (msm_comm_compare_dma_planes(inst, mbuf,
|
||||
dma_planes)) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
|
@ -214,7 +214,7 @@ void msm_comm_put_vidc_buffer(struct msm_vidc_inst *inst,
|
||||
void handle_release_buffer_reference(struct msm_vidc_inst *inst,
|
||||
struct msm_vidc_buffer *mbuf);
|
||||
int msm_comm_vb2_buffer_done(struct msm_vidc_inst *inst,
|
||||
struct vb2_buffer *vb);
|
||||
struct msm_vidc_buffer *mbuf);
|
||||
int msm_comm_flush_vidc_buffer(struct msm_vidc_inst *inst,
|
||||
struct msm_vidc_buffer *mbuf);
|
||||
int msm_comm_unmap_vidc_buffer(struct msm_vidc_inst *inst,
|
||||
|
Loading…
x
Reference in New Issue
Block a user