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 <hverkuil-cisco@xs4all.nl>
Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
This commit is contained in:
Hans Verkuil
2019-10-11 06:32:41 -03:00
committed by Mauro Carvalho Chehab
parent 137272cdf7
commit f8cca8c97a
2 changed files with 128 additions and 35 deletions

View File

@@ -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)
{