Re: [RFC PATCH 2/2] [media] videobuf2: return -EPIPE from DQBUF after the last buffer
Hi Laurent, Am Dienstag, den 03.02.2015, 13:20 +0200 schrieb Laurent Pinchart: On Monday 02 February 2015 15:00:51 Hans Verkuil wrote: On 01/22/2015 12:28 PM, Philipp Zabel wrote: If the last buffer was dequeued from a capture queue, let poll return immediately and let DQBUF return -EPIPE to signal there will no more buffers to dequeue until STREAMOFF. This looks OK to me, although I would like to see comments from others as well. Of course, this needs to be documented in the spec as well. I haven't followed the V4L2 codec API discussion during ELC-E. Could someone briefly expose the rationale for this and the codec draining flow ? The explanation should probably included in the documentation. This is the draining flow as written down in the notes: The decoder draining flow starts with the application making the driver aware of its intentions by calling VIDIOC_DECODER_CMD with V4L2_DEC_CMD_STOP. The driver processes the remaining buffers on the OUTPUT queue. Once all CAPTURE buffers produced from those are ready to dequeue, it sends a V4L2_EVENT_EOS. The application then dequeues buffers from the CAPTURE queue until it encounters a buffer with V4L2_BUF_FLAG_LAST set. This buffer may already be empty due to hardware limitations. Alternatively, the application may simply continue to dequeue (possibly empty) buffers until the VIDIOC_DQBUF ioctl returns -EPIPE. To resume decoding, the application can call VIDIOC_DECODER_CMD with V4L2_CMD_START without the need to stop streaming. This should work the same for encoding. The rationale for using -EPIPE was IIRC that it allows for simpler code (DQBUF loop until error). Also it works without the newest kernel headers that #define V4L2_BUF_FLAG_LAST. I don't remember if we talked about what should happen to new buffers queued via QBUF on the OUTPUT queue while in draining mode, but I suppose the driver should just hold them until V4L2_CMD_START is called. Existing applications will receive -EPIPE from DQBUF now. Have potential breakages been taken into account ? We can continue to produce empty frames this way, which are currently used to signal the last frame in s5p-mfc. I am not aware of other unspecified mechanisms in use. regards Philipp -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [RFC PATCH 2/2] [media] videobuf2: return -EPIPE from DQBUF after the last buffer
On Monday 02 February 2015 15:00:51 Hans Verkuil wrote: On 01/22/2015 12:28 PM, Philipp Zabel wrote: If the last buffer was dequeued from a capture queue, let poll return immediately and let DQBUF return -EPIPE to signal there will no more buffers to dequeue until STREAMOFF. This looks OK to me, although I would like to see comments from others as well. Of course, this needs to be documented in the spec as well. I haven't followed the V4L2 codec API discussion during ELC-E. Could someone briefly expose the rationale for this and the codec draining flow ? The explanation should probably included in the documentation. Existing applications will receive -EPIPE from DQBUF now. Have potential breakages been taken into account ? Signed-off-by: Philipp Zabel p.za...@pengutronix.de --- TODO: (How) should the last_buffer_dequeud flag be cleared in reaction to V4L2_DEC_CMD_START? I would suggest an inline function in videobuf2-core.h that clears the flag and that drivers can call. I don't think the vb2 core can detect when it is OK to clear the flag, it needs to be told by the driver (correct me if I am wrong). -- Regards, Laurent Pinchart -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [RFC PATCH 2/2] [media] videobuf2: return -EPIPE from DQBUF after the last buffer
On 01/22/2015 12:28 PM, Philipp Zabel wrote: If the last buffer was dequeued from a capture queue, let poll return immediately and let DQBUF return -EPIPE to signal there will no more buffers to dequeue until STREAMOFF. This looks OK to me, although I would like to see comments from others as well. Of course, this needs to be documented in the spec as well. Signed-off-by: Philipp Zabel p.za...@pengutronix.de --- TODO: (How) should the last_buffer_dequeud flag be cleared in reaction to V4L2_DEC_CMD_START? I would suggest an inline function in videobuf2-core.h that clears the flag and that drivers can call. I don't think the vb2 core can detect when it is OK to clear the flag, it needs to be told by the driver (correct me if I am wrong). Regards, Hans --- drivers/media/v4l2-core/v4l2-mem2mem.c | 10 +- drivers/media/v4l2-core/videobuf2-core.c | 18 +- include/media/videobuf2-core.h | 1 + 3 files changed, 27 insertions(+), 2 deletions(-) diff --git a/drivers/media/v4l2-core/v4l2-mem2mem.c b/drivers/media/v4l2-core/v4l2-mem2mem.c index 80c588f..1b5b432 100644 --- a/drivers/media/v4l2-core/v4l2-mem2mem.c +++ b/drivers/media/v4l2-core/v4l2-mem2mem.c @@ -564,8 +564,16 @@ unsigned int v4l2_m2m_poll(struct file *file, struct v4l2_m2m_ctx *m2m_ctx, if (list_empty(src_q-done_list)) poll_wait(file, src_q-done_wq, wait); - if (list_empty(dst_q-done_list)) + if (list_empty(dst_q-done_list)) { + /* + * If the last buffer was dequeued from the capture queue, + * return immediately. DQBUF will return -EPIPE. + */ + if (dst_q-last_buffer_dequeued) + return rc | POLLIN | POLLRDNORM; + poll_wait(file, dst_q-done_wq, wait); + } if (m2m_ctx-m2m_dev-m2m_ops-lock) m2m_ctx-m2m_dev-m2m_ops-lock(m2m_ctx-priv); diff --git a/drivers/media/v4l2-core/videobuf2-core.c b/drivers/media/v4l2-core/videobuf2-core.c index d09a891..c2c2eac 100644 --- a/drivers/media/v4l2-core/videobuf2-core.c +++ b/drivers/media/v4l2-core/videobuf2-core.c @@ -2046,6 +2046,10 @@ static int vb2_internal_dqbuf(struct vb2_queue *q, struct v4l2_buffer *b, bool n struct vb2_buffer *vb = NULL; int ret; + if (q-last_buffer_dequeued) { + dprintk(3, last buffer dequeued already\n); + return -EPIPE; + } if (b-type != q-type) { dprintk(1, invalid buffer type\n); return -EINVAL; @@ -2073,6 +2077,9 @@ static int vb2_internal_dqbuf(struct vb2_queue *q, struct v4l2_buffer *b, bool n /* Remove from videobuf queue */ list_del(vb-queued_entry); q-queued_count--; + if (!V4L2_TYPE_IS_OUTPUT(q-type) + vb-v4l2_buf.flags V4L2_BUF_FLAG_LAST) + q-last_buffer_dequeued = true; /* go back to dequeued state */ __vb2_dqbuf(vb); @@ -2286,6 +2293,7 @@ static int vb2_internal_streamoff(struct vb2_queue *q, enum v4l2_buf_type type) */ __vb2_queue_cancel(q); q-waiting_for_buffers = !V4L2_TYPE_IS_OUTPUT(q-type); + q-last_buffer_dequeued = false; dprintk(3, successful\n); return 0; @@ -2628,8 +2636,16 @@ unsigned int vb2_poll(struct vb2_queue *q, struct file *file, poll_table *wait) if (V4L2_TYPE_IS_OUTPUT(q-type) q-queued_count q-num_buffers) return res | POLLOUT | POLLWRNORM; - if (list_empty(q-done_list)) + if (list_empty(q-done_list)) { + /* + * If the last buffer was dequeued from a capture queue, + * return immediately. DQBUF will return -EPIPE. + */ + if (!V4L2_TYPE_IS_OUTPUT(q-type) q-last_buffer_dequeued) + return res | POLLIN | POLLRDNORM; + poll_wait(file, q-done_wq, wait); + } /* * Take first buffer available for dequeuing. diff --git a/include/media/videobuf2-core.h b/include/media/videobuf2-core.h index bd2cec2..ca337bf 100644 --- a/include/media/videobuf2-core.h +++ b/include/media/videobuf2-core.h @@ -429,6 +429,7 @@ struct vb2_queue { unsigned intstart_streaming_called:1; unsigned interror:1; unsigned intwaiting_for_buffers:1; + unsigned intlast_buffer_dequeued:1; struct vb2_fileio_data *fileio; struct vb2_threadio_data*threadio; -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [RFC PATCH 2/2] [media] videobuf2: return -EPIPE from DQBUF after the last buffer
Am Montag, den 02.02.2015, 15:00 +0100 schrieb Hans Verkuil: On 01/22/2015 12:28 PM, Philipp Zabel wrote: If the last buffer was dequeued from a capture queue, let poll return immediately and let DQBUF return -EPIPE to signal there will no more buffers to dequeue until STREAMOFF. This looks OK to me, although I would like to see comments from others as well. Of course, this needs to be documented in the spec as well. Thanks, I'll fix that in the next round. Signed-off-by: Philipp Zabel p.za...@pengutronix.de --- TODO: (How) should the last_buffer_dequeud flag be cleared in reaction to V4L2_DEC_CMD_START? I would suggest an inline function in videobuf2-core.h that clears the flag and that drivers can call. I don't think the vb2 core can detect when it is OK to clear the flag, it needs to be told by the driver (correct me if I am wrong). No, I think you are right that this should be done explicitly. I'll add an inline function next time. regards Philipp -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[RFC PATCH 2/2] [media] videobuf2: return -EPIPE from DQBUF after the last buffer
If the last buffer was dequeued from a capture queue, let poll return immediately and let DQBUF return -EPIPE to signal there will no more buffers to dequeue until STREAMOFF. Signed-off-by: Philipp Zabel p.za...@pengutronix.de --- TODO: (How) should the last_buffer_dequeud flag be cleared in reaction to V4L2_DEC_CMD_START? --- drivers/media/v4l2-core/v4l2-mem2mem.c | 10 +- drivers/media/v4l2-core/videobuf2-core.c | 18 +- include/media/videobuf2-core.h | 1 + 3 files changed, 27 insertions(+), 2 deletions(-) diff --git a/drivers/media/v4l2-core/v4l2-mem2mem.c b/drivers/media/v4l2-core/v4l2-mem2mem.c index 80c588f..1b5b432 100644 --- a/drivers/media/v4l2-core/v4l2-mem2mem.c +++ b/drivers/media/v4l2-core/v4l2-mem2mem.c @@ -564,8 +564,16 @@ unsigned int v4l2_m2m_poll(struct file *file, struct v4l2_m2m_ctx *m2m_ctx, if (list_empty(src_q-done_list)) poll_wait(file, src_q-done_wq, wait); - if (list_empty(dst_q-done_list)) + if (list_empty(dst_q-done_list)) { + /* +* If the last buffer was dequeued from the capture queue, +* return immediately. DQBUF will return -EPIPE. +*/ + if (dst_q-last_buffer_dequeued) + return rc | POLLIN | POLLRDNORM; + poll_wait(file, dst_q-done_wq, wait); + } if (m2m_ctx-m2m_dev-m2m_ops-lock) m2m_ctx-m2m_dev-m2m_ops-lock(m2m_ctx-priv); diff --git a/drivers/media/v4l2-core/videobuf2-core.c b/drivers/media/v4l2-core/videobuf2-core.c index d09a891..c2c2eac 100644 --- a/drivers/media/v4l2-core/videobuf2-core.c +++ b/drivers/media/v4l2-core/videobuf2-core.c @@ -2046,6 +2046,10 @@ static int vb2_internal_dqbuf(struct vb2_queue *q, struct v4l2_buffer *b, bool n struct vb2_buffer *vb = NULL; int ret; + if (q-last_buffer_dequeued) { + dprintk(3, last buffer dequeued already\n); + return -EPIPE; + } if (b-type != q-type) { dprintk(1, invalid buffer type\n); return -EINVAL; @@ -2073,6 +2077,9 @@ static int vb2_internal_dqbuf(struct vb2_queue *q, struct v4l2_buffer *b, bool n /* Remove from videobuf queue */ list_del(vb-queued_entry); q-queued_count--; + if (!V4L2_TYPE_IS_OUTPUT(q-type) + vb-v4l2_buf.flags V4L2_BUF_FLAG_LAST) + q-last_buffer_dequeued = true; /* go back to dequeued state */ __vb2_dqbuf(vb); @@ -2286,6 +2293,7 @@ static int vb2_internal_streamoff(struct vb2_queue *q, enum v4l2_buf_type type) */ __vb2_queue_cancel(q); q-waiting_for_buffers = !V4L2_TYPE_IS_OUTPUT(q-type); + q-last_buffer_dequeued = false; dprintk(3, successful\n); return 0; @@ -2628,8 +2636,16 @@ unsigned int vb2_poll(struct vb2_queue *q, struct file *file, poll_table *wait) if (V4L2_TYPE_IS_OUTPUT(q-type) q-queued_count q-num_buffers) return res | POLLOUT | POLLWRNORM; - if (list_empty(q-done_list)) + if (list_empty(q-done_list)) { + /* +* If the last buffer was dequeued from a capture queue, +* return immediately. DQBUF will return -EPIPE. +*/ + if (!V4L2_TYPE_IS_OUTPUT(q-type) q-last_buffer_dequeued) + return res | POLLIN | POLLRDNORM; + poll_wait(file, q-done_wq, wait); + } /* * Take first buffer available for dequeuing. diff --git a/include/media/videobuf2-core.h b/include/media/videobuf2-core.h index bd2cec2..ca337bf 100644 --- a/include/media/videobuf2-core.h +++ b/include/media/videobuf2-core.h @@ -429,6 +429,7 @@ struct vb2_queue { unsigned intstart_streaming_called:1; unsigned interror:1; unsigned intwaiting_for_buffers:1; + unsigned intlast_buffer_dequeued:1; struct vb2_fileio_data *fileio; struct vb2_threadio_data*threadio; -- 2.1.4 -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html