From f8cca8c97a63d77f48334cde81d15014f43530ef Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Fri, 11 Oct 2019 06:32:41 -0300 Subject: media: v4l2-mem2mem: support held capture buffers Check for held buffers that are ready to be returned to vb2 in __v4l2_m2m_try_queue(). This avoids drivers having to handle this case. Add v4l2_m2m_buf_done_and_job_finish() to correctly return source and destination buffers and mark the job as finished while taking a held destination buffer into account (i.e. that buffer won't be returned). This has to be done while job_spinlock is held to avoid race conditions. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- include/media/v4l2-mem2mem.h | 33 +++++++++++++++++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-) (limited to 'include/media') diff --git a/include/media/v4l2-mem2mem.h b/include/media/v4l2-mem2mem.h index 0b9c3a287061..229d9f5d4370 100644 --- a/include/media/v4l2-mem2mem.h +++ b/include/media/v4l2-mem2mem.h @@ -21,7 +21,8 @@ * callback. * The job does NOT have to end before this callback returns * (and it will be the usual case). When the job finishes, - * v4l2_m2m_job_finish() has to be called. + * v4l2_m2m_job_finish() or v4l2_m2m_buf_done_and_job_finish() + * has to be called. * @job_ready: optional. Should return 0 if the driver does not have a job * fully prepared to run yet (i.e. it will not be able to finish a * transaction without sleeping). If not provided, it will be @@ -33,7 +34,8 @@ * stop the device safely; e.g. in the next interrupt handler), * even if the transaction would not have been finished by then. * After the driver performs the necessary steps, it has to call - * v4l2_m2m_job_finish() (as if the transaction ended normally). + * v4l2_m2m_job_finish() or v4l2_m2m_buf_done_and_job_finish() as + * if the transaction ended normally. * This function does not have to (and will usually not) wait * until the device enters a state when it can be stopped. */ @@ -173,6 +175,33 @@ void v4l2_m2m_try_schedule(struct v4l2_m2m_ctx *m2m_ctx); void v4l2_m2m_job_finish(struct v4l2_m2m_dev *m2m_dev, struct v4l2_m2m_ctx *m2m_ctx); +/** + * v4l2_m2m_buf_done_and_job_finish() - return source/destination buffers with + * state and inform the framework that a job has been finished and have it + * clean up + * + * @m2m_dev: opaque pointer to the internal data to handle M2M context + * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx + * @state: vb2 buffer state passed to v4l2_m2m_buf_done(). + * + * Drivers that set V4L2_BUF_CAP_SUPPORTS_M2M_HOLD_CAPTURE_BUF must use this + * function instead of job_finish() to take held buffers into account. It is + * optional for other drivers. + * + * This function removes the source buffer from the ready list and returns + * it with the given state. The same is done for the destination buffer, unless + * it is marked 'held'. In that case the buffer is kept on the ready list. + * + * After that the job is finished (see job_finish()). + * + * This allows for multiple output buffers to be used to fill in a single + * capture buffer. This is typically used by stateless decoders where + * multiple e.g. H.264 slices contribute to a single decoded frame. + */ +void v4l2_m2m_buf_done_and_job_finish(struct v4l2_m2m_dev *m2m_dev, + struct v4l2_m2m_ctx *m2m_ctx, + enum vb2_buffer_state state); + static inline void v4l2_m2m_buf_done(struct vb2_v4l2_buffer *buf, enum vb2_buffer_state state) { -- cgit v1.2.3