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:

committed by
Mauro Carvalho Chehab

parent
137272cdf7
commit
f8cca8c97a
@@ -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)
|
||||
{
|
||||
|
Reference in New Issue
Block a user