diff mbox

[v4,1/9] media: v4l2-mem2mem: extend m2m APIs for more accurate buffer management

Message ID 1480583001-32236-2-git-send-email-stanimir.varbanov@linaro.org (mailing list archive)
State New, archived
Headers show

Commit Message

Stanimir Varbanov Dec. 1, 2016, 9:03 a.m. UTC
this add functions for:
  - remove buffers from src/dst queue by index
  - remove exact buffer from src/dst queue

also extends m2m API to iterate over a list of src/dst buffers
in safely and non-safely manner.

Signed-off-by: Stanimir Varbanov <stanimir.varbanov@linaro.org>
---
 drivers/media/v4l2-core/v4l2-mem2mem.c | 37 +++++++++++++++
 include/media/v4l2-mem2mem.h           | 83 ++++++++++++++++++++++++++++++++++
 2 files changed, 120 insertions(+)

Comments

kernel test robot Dec. 3, 2016, 12:56 a.m. UTC | #1
Hi Stanimir,

[auto build test WARNING on linuxtv-media/master]
[also build test WARNING on v4.9-rc7 next-20161202]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url:    https://github.com/0day-ci/linux/commits/Stanimir-Varbanov/Qualcomm-video-decoder-encoder-driver/20161203-054705
base:   git://linuxtv.org/media_tree.git master
reproduce: make htmldocs

All warnings (new ones prefixed by >>):

   make[3]: warning: jobserver unavailable: using -j1.  Add '+' to parent make rule.
   include/linux/init.h:1: warning: no structured comments found
   include/linux/workqueue.h:392: warning: No description found for parameter '...'
   include/linux/workqueue.h:392: warning: Excess function parameter 'args' description in 'alloc_workqueue'
   include/linux/workqueue.h:413: warning: No description found for parameter '...'
   include/linux/workqueue.h:413: warning: Excess function parameter 'args' description in 'alloc_ordered_workqueue'
   include/linux/kthread.h:26: warning: No description found for parameter '...'
   kernel/sys.c:1: warning: no structured comments found
   drivers/dma-buf/seqno-fence.c:1: warning: no structured comments found
   include/linux/fence-array.h:61: warning: No description found for parameter 'fence'
   include/sound/core.h:324: warning: No description found for parameter '...'
   include/sound/core.h:335: warning: No description found for parameter '...'
   include/sound/core.h:388: warning: No description found for parameter '...'
   drivers/media/dvb-core/dvb_frontend.h:677: warning: No description found for parameter 'refcount'
   include/media/media-entity.h:1054: warning: No description found for parameter '...'
>> include/media/v4l2-mem2mem.h:446: warning: No description found for parameter 'b'
   include/media/v4l2-mem2mem.h:454: warning: No description found for parameter 'b'
   include/media/v4l2-mem2mem.h:463: warning: No description found for parameter 'b'
>> include/media/v4l2-mem2mem.h:463: warning: No description found for parameter 'n'
   include/media/v4l2-mem2mem.h:472: warning: No description found for parameter 'b'
   include/media/v4l2-mem2mem.h:472: warning: No description found for parameter 'n'
>> include/media/v4l2-mem2mem.h:533: warning: No description found for parameter 'vbuf'
   include/media/v4l2-mem2mem.h:543: warning: No description found for parameter 'vbuf'
   include/media/v4l2-mem2mem.h:555: warning: No description found for parameter 'vbuf'
   include/net/mac80211.h:3207: ERROR: Unexpected indentation.
   include/net/mac80211.h:3210: WARNING: Block quote ends without a blank line; unexpected unindent.
   include/net/mac80211.h:3212: ERROR: Unexpected indentation.
   include/net/mac80211.h:3213: WARNING: Block quote ends without a blank line; unexpected unindent.
   include/net/mac80211.h:1772: ERROR: Unexpected indentation.
   include/net/mac80211.h:1776: WARNING: Block quote ends without a blank line; unexpected unindent.
   kernel/sched/fair.c:7259: WARNING: Inline emphasis start-string without end-string.
   kernel/time/timer.c:1240: ERROR: Unexpected indentation.
   kernel/time/timer.c:1242: ERROR: Unexpected indentation.
   kernel/time/timer.c:1243: WARNING: Block quote ends without a blank line; unexpected unindent.
   include/linux/wait.h:121: WARNING: Block quote ends without a blank line; unexpected unindent.
   include/linux/wait.h:124: ERROR: Unexpected indentation.
   include/linux/wait.h:126: WARNING: Block quote ends without a blank line; unexpected unindent.
   kernel/time/hrtimer.c:1021: WARNING: Block quote ends without a blank line; unexpected unindent.
   kernel/signal.c:317: WARNING: Inline literal start-string without end-string.
   drivers/base/firmware_class.c:1348: WARNING: Bullet list ends without a blank line; unexpected unindent.
   drivers/message/fusion/mptbase.c:5054: WARNING: Definition list ends without a blank line; unexpected unindent.
   drivers/tty/serial/serial_core.c:1893: WARNING: Definition list ends without a blank line; unexpected unindent.
   include/linux/spi/spi.h:369: ERROR: Unexpected indentation.
   WARNING: dvipng command 'dvipng' cannot be run (needed for math display), check the imgmath_dvipng setting

vim +/b +446 include/media/v4l2-mem2mem.h

   440	 * v4l2_m2m_for_each_dst_buf() - iterate over a list of destination ready
   441	 * buffers
   442	 *
   443	 * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx
   444	 */
   445	#define v4l2_m2m_for_each_dst_buf(m2m_ctx, b)	\
 > 446		list_for_each_entry(b, &m2m_ctx->cap_q_ctx.rdy_queue, list)
   447	
   448	/**
   449	 * v4l2_m2m_for_each_src_buf() - iterate over a list of source ready buffers
   450	 *
   451	 * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx
   452	 */
   453	#define v4l2_m2m_for_each_src_buf(m2m_ctx, b)	\
   454		list_for_each_entry(b, &m2m_ctx->out_q_ctx.rdy_queue, list)
   455	
   456	/**
   457	 * v4l2_m2m_for_each_dst_buf_safe() - iterate over a list of destination ready
   458	 * buffers safely
   459	 *
   460	 * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx
   461	 */
   462	#define v4l2_m2m_for_each_dst_buf_safe(m2m_ctx, b, n)	\
 > 463		list_for_each_entry_safe(b, n, &m2m_ctx->cap_q_ctx.rdy_queue, list)
   464	
   465	/**
   466	 * v4l2_m2m_for_each_src_buf_safe() - iterate over a list of source ready
   467	 * buffers safely
   468	 *
   469	 * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx
   470	 */
   471	#define v4l2_m2m_for_each_src_buf_safe(m2m_ctx, b, n)	\
   472		list_for_each_entry_safe(b, n, &m2m_ctx->out_q_ctx.rdy_queue, list)
   473	
   474	/**
   475	 * v4l2_m2m_get_src_vq() - return vb2_queue for source buffers
   476	 *
   477	 * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx
   478	 */
   479	static inline
   480	struct vb2_queue *v4l2_m2m_get_src_vq(struct v4l2_m2m_ctx *m2m_ctx)
   481	{
   482		return &m2m_ctx->out_q_ctx.q;
   483	}
   484	
   485	/**
   486	 * v4l2_m2m_get_dst_vq() - return vb2_queue for destination buffers
   487	 *
   488	 * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx
   489	 */
   490	static inline
   491	struct vb2_queue *v4l2_m2m_get_dst_vq(struct v4l2_m2m_ctx *m2m_ctx)
   492	{
   493		return &m2m_ctx->cap_q_ctx.q;
   494	}
   495	
   496	/**
   497	 * v4l2_m2m_buf_remove() - take off a buffer from the list of ready buffers and
   498	 * return it
   499	 *
   500	 * @q_ctx: pointer to struct @v4l2_m2m_queue_ctx
   501	 */
   502	void *v4l2_m2m_buf_remove(struct v4l2_m2m_queue_ctx *q_ctx);
   503	
   504	/**
   505	 * v4l2_m2m_src_buf_remove() - take off a source buffer from the list of ready
   506	 * buffers and return it
   507	 *
   508	 * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx
   509	 */
   510	static inline void *v4l2_m2m_src_buf_remove(struct v4l2_m2m_ctx *m2m_ctx)
   511	{
   512		return v4l2_m2m_buf_remove(&m2m_ctx->out_q_ctx);
   513	}
   514	
   515	/**
   516	 * v4l2_m2m_dst_buf_remove() - take off a destination buffer from the list of
   517	 * ready buffers and return it
   518	 *
   519	 * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx
   520	 */
   521	static inline void *v4l2_m2m_dst_buf_remove(struct v4l2_m2m_ctx *m2m_ctx)
   522	{
   523		return v4l2_m2m_buf_remove(&m2m_ctx->cap_q_ctx);
   524	}
   525	
   526	/**
   527	 * v4l2_m2m_buf_remove_exact() - take off exact buffer from the list of ready
   528	 * buffers
   529	 *
   530	 * @q_ctx: pointer to struct @v4l2_m2m_queue_ctx
   531	 */
   532	void v4l2_m2m_buf_remove_exact(struct v4l2_m2m_queue_ctx *q_ctx,
 > 533				       struct vb2_v4l2_buffer *vbuf);
   534	
   535	/**
   536	 * v4l2_m2m_src_buf_remove_exact() - take off exact source buffer from the list

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation
Hans Verkuil Dec. 5, 2016, 11:25 a.m. UTC | #2
On 12/01/2016 10:03 AM, Stanimir Varbanov wrote:
> this add functions for:
>   - remove buffers from src/dst queue by index
>   - remove exact buffer from src/dst queue
> 
> also extends m2m API to iterate over a list of src/dst buffers
> in safely and non-safely manner.
> 
> Signed-off-by: Stanimir Varbanov <stanimir.varbanov@linaro.org>
> ---
>  drivers/media/v4l2-core/v4l2-mem2mem.c | 37 +++++++++++++++
>  include/media/v4l2-mem2mem.h           | 83 ++++++++++++++++++++++++++++++++++
>  2 files changed, 120 insertions(+)
> 
> diff --git a/drivers/media/v4l2-core/v4l2-mem2mem.c b/drivers/media/v4l2-core/v4l2-mem2mem.c
> index 6bc27e7b2a33..d689e7bb964f 100644
> --- a/drivers/media/v4l2-core/v4l2-mem2mem.c
> +++ b/drivers/media/v4l2-core/v4l2-mem2mem.c
> @@ -126,6 +126,43 @@ void *v4l2_m2m_buf_remove(struct v4l2_m2m_queue_ctx *q_ctx)
>  }
>  EXPORT_SYMBOL_GPL(v4l2_m2m_buf_remove);
>  
> +void v4l2_m2m_buf_remove_exact(struct v4l2_m2m_queue_ctx *q_ctx,
> +			       struct vb2_v4l2_buffer *vbuf)

I'd call this v4l2_m2m_buf_remove_by_buf to be consistent with _by_idx.

Other than that, this looks OK.

Regards,

	Hans

> +{
> +	struct v4l2_m2m_buffer *b;
> +	unsigned long flags;
> +
> +	spin_lock_irqsave(&q_ctx->rdy_spinlock, flags);
> +	b = container_of(vbuf, struct v4l2_m2m_buffer, vb);
> +	list_del(&b->list);
> +	q_ctx->num_rdy--;
> +	spin_unlock_irqrestore(&q_ctx->rdy_spinlock, flags);
> +}
> +EXPORT_SYMBOL_GPL(v4l2_m2m_buf_remove_exact);
> +
> +struct vb2_v4l2_buffer *
> +v4l2_m2m_buf_remove_by_idx(struct v4l2_m2m_queue_ctx *q_ctx, unsigned int idx)
> +
> +{
> +	struct v4l2_m2m_buffer *b, *tmp;
> +	struct vb2_v4l2_buffer *ret = NULL;
> +	unsigned long flags;
> +
> +	spin_lock_irqsave(&q_ctx->rdy_spinlock, flags);
> +	list_for_each_entry_safe(b, tmp, &q_ctx->rdy_queue, list) {
> +		if (b->vb.vb2_buf.index == idx) {
> +			list_del(&b->list);
> +			q_ctx->num_rdy--;
> +			ret = &b->vb;
> +			break;
> +		}
> +	}
> +	spin_unlock_irqrestore(&q_ctx->rdy_spinlock, flags);
> +
> +	return ret;
> +}
> +EXPORT_SYMBOL_GPL(v4l2_m2m_buf_remove_by_idx);
> +
>  /*
>   * Scheduling handlers
>   */
> diff --git a/include/media/v4l2-mem2mem.h b/include/media/v4l2-mem2mem.h
> index 3ccd01bd245e..c8632c52d5e2 100644
> --- a/include/media/v4l2-mem2mem.h
> +++ b/include/media/v4l2-mem2mem.h
> @@ -437,6 +437,41 @@ static inline void *v4l2_m2m_next_dst_buf(struct v4l2_m2m_ctx *m2m_ctx)
>  }
>  
>  /**
> + * v4l2_m2m_for_each_dst_buf() - iterate over a list of destination ready
> + * buffers
> + *
> + * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx
> + */
> +#define v4l2_m2m_for_each_dst_buf(m2m_ctx, b)	\
> +	list_for_each_entry(b, &m2m_ctx->cap_q_ctx.rdy_queue, list)
> +
> +/**
> + * v4l2_m2m_for_each_src_buf() - iterate over a list of source ready buffers
> + *
> + * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx
> + */
> +#define v4l2_m2m_for_each_src_buf(m2m_ctx, b)	\
> +	list_for_each_entry(b, &m2m_ctx->out_q_ctx.rdy_queue, list)
> +
> +/**
> + * v4l2_m2m_for_each_dst_buf_safe() - iterate over a list of destination ready
> + * buffers safely
> + *
> + * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx
> + */
> +#define v4l2_m2m_for_each_dst_buf_safe(m2m_ctx, b, n)	\
> +	list_for_each_entry_safe(b, n, &m2m_ctx->cap_q_ctx.rdy_queue, list)
> +
> +/**
> + * v4l2_m2m_for_each_src_buf_safe() - iterate over a list of source ready
> + * buffers safely
> + *
> + * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx
> + */
> +#define v4l2_m2m_for_each_src_buf_safe(m2m_ctx, b, n)	\
> +	list_for_each_entry_safe(b, n, &m2m_ctx->out_q_ctx.rdy_queue, list)
> +
> +/**
>   * v4l2_m2m_get_src_vq() - return vb2_queue for source buffers
>   *
>   * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx
> @@ -488,6 +523,54 @@ static inline void *v4l2_m2m_dst_buf_remove(struct v4l2_m2m_ctx *m2m_ctx)
>  	return v4l2_m2m_buf_remove(&m2m_ctx->cap_q_ctx);
>  }
>  
> +/**
> + * v4l2_m2m_buf_remove_exact() - take off exact buffer from the list of ready
> + * buffers
> + *
> + * @q_ctx: pointer to struct @v4l2_m2m_queue_ctx
> + */
> +void v4l2_m2m_buf_remove_exact(struct v4l2_m2m_queue_ctx *q_ctx,
> +			       struct vb2_v4l2_buffer *vbuf);
> +
> +/**
> + * v4l2_m2m_src_buf_remove_exact() - take off exact source buffer from the list
> + * of ready buffers
> + *
> + * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx
> + */
> +static inline void v4l2_m2m_src_buf_remove_exact(struct v4l2_m2m_ctx *m2m_ctx,
> +						 struct vb2_v4l2_buffer *vbuf)
> +{
> +	v4l2_m2m_buf_remove_exact(&m2m_ctx->out_q_ctx, vbuf);
> +}
> +
> +/**
> + * v4l2_m2m_src_buf_remove_exact() - take off exact destination buffer from the
> + * list of ready buffers
> + *
> + * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx
> + */
> +static inline void v4l2_m2m_dst_buf_remove_exact(struct v4l2_m2m_ctx *m2m_ctx,
> +						 struct vb2_v4l2_buffer *vbuf)
> +{
> +	v4l2_m2m_buf_remove_exact(&m2m_ctx->cap_q_ctx, vbuf);
> +}
> +
> +struct vb2_v4l2_buffer *
> +v4l2_m2m_buf_remove_by_idx(struct v4l2_m2m_queue_ctx *q_ctx, unsigned int idx);
> +
> +static inline struct vb2_v4l2_buffer *
> +v4l2_m2m_src_buf_remove_by_idx(struct v4l2_m2m_ctx *m2m_ctx, unsigned int idx)
> +{
> +	return v4l2_m2m_buf_remove_by_idx(&m2m_ctx->out_q_ctx, idx);
> +}
> +
> +static inline struct vb2_v4l2_buffer *
> +v4l2_m2m_dst_buf_remove_by_idx(struct v4l2_m2m_ctx *m2m_ctx, unsigned int idx)
> +{
> +	return v4l2_m2m_buf_remove_by_idx(&m2m_ctx->cap_q_ctx, idx);
> +}
> +
>  /* v4l2 ioctl helpers */
>  
>  int v4l2_m2m_ioctl_reqbufs(struct file *file, void *priv,
> 

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Stanimir Varbanov Dec. 5, 2016, 12:26 p.m. UTC | #3
Hi Hans,

On 12/05/2016 01:25 PM, Hans Verkuil wrote:
> On 12/01/2016 10:03 AM, Stanimir Varbanov wrote:
>> this add functions for:
>>   - remove buffers from src/dst queue by index
>>   - remove exact buffer from src/dst queue
>>
>> also extends m2m API to iterate over a list of src/dst buffers
>> in safely and non-safely manner.
>>
>> Signed-off-by: Stanimir Varbanov <stanimir.varbanov@linaro.org>
>> ---
>>  drivers/media/v4l2-core/v4l2-mem2mem.c | 37 +++++++++++++++
>>  include/media/v4l2-mem2mem.h           | 83 ++++++++++++++++++++++++++++++++++
>>  2 files changed, 120 insertions(+)
>>
>> diff --git a/drivers/media/v4l2-core/v4l2-mem2mem.c b/drivers/media/v4l2-core/v4l2-mem2mem.c
>> index 6bc27e7b2a33..d689e7bb964f 100644
>> --- a/drivers/media/v4l2-core/v4l2-mem2mem.c
>> +++ b/drivers/media/v4l2-core/v4l2-mem2mem.c
>> @@ -126,6 +126,43 @@ void *v4l2_m2m_buf_remove(struct v4l2_m2m_queue_ctx *q_ctx)
>>  }
>>  EXPORT_SYMBOL_GPL(v4l2_m2m_buf_remove);
>>  
>> +void v4l2_m2m_buf_remove_exact(struct v4l2_m2m_queue_ctx *q_ctx,
>> +			       struct vb2_v4l2_buffer *vbuf)
> 
> I'd call this v4l2_m2m_buf_remove_by_buf to be consistent with _by_idx.

Thanks, I will rename it.
diff mbox

Patch

diff --git a/drivers/media/v4l2-core/v4l2-mem2mem.c b/drivers/media/v4l2-core/v4l2-mem2mem.c
index 6bc27e7b2a33..d689e7bb964f 100644
--- a/drivers/media/v4l2-core/v4l2-mem2mem.c
+++ b/drivers/media/v4l2-core/v4l2-mem2mem.c
@@ -126,6 +126,43 @@  void *v4l2_m2m_buf_remove(struct v4l2_m2m_queue_ctx *q_ctx)
 }
 EXPORT_SYMBOL_GPL(v4l2_m2m_buf_remove);
 
+void v4l2_m2m_buf_remove_exact(struct v4l2_m2m_queue_ctx *q_ctx,
+			       struct vb2_v4l2_buffer *vbuf)
+{
+	struct v4l2_m2m_buffer *b;
+	unsigned long flags;
+
+	spin_lock_irqsave(&q_ctx->rdy_spinlock, flags);
+	b = container_of(vbuf, struct v4l2_m2m_buffer, vb);
+	list_del(&b->list);
+	q_ctx->num_rdy--;
+	spin_unlock_irqrestore(&q_ctx->rdy_spinlock, flags);
+}
+EXPORT_SYMBOL_GPL(v4l2_m2m_buf_remove_exact);
+
+struct vb2_v4l2_buffer *
+v4l2_m2m_buf_remove_by_idx(struct v4l2_m2m_queue_ctx *q_ctx, unsigned int idx)
+
+{
+	struct v4l2_m2m_buffer *b, *tmp;
+	struct vb2_v4l2_buffer *ret = NULL;
+	unsigned long flags;
+
+	spin_lock_irqsave(&q_ctx->rdy_spinlock, flags);
+	list_for_each_entry_safe(b, tmp, &q_ctx->rdy_queue, list) {
+		if (b->vb.vb2_buf.index == idx) {
+			list_del(&b->list);
+			q_ctx->num_rdy--;
+			ret = &b->vb;
+			break;
+		}
+	}
+	spin_unlock_irqrestore(&q_ctx->rdy_spinlock, flags);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(v4l2_m2m_buf_remove_by_idx);
+
 /*
  * Scheduling handlers
  */
diff --git a/include/media/v4l2-mem2mem.h b/include/media/v4l2-mem2mem.h
index 3ccd01bd245e..c8632c52d5e2 100644
--- a/include/media/v4l2-mem2mem.h
+++ b/include/media/v4l2-mem2mem.h
@@ -437,6 +437,41 @@  static inline void *v4l2_m2m_next_dst_buf(struct v4l2_m2m_ctx *m2m_ctx)
 }
 
 /**
+ * v4l2_m2m_for_each_dst_buf() - iterate over a list of destination ready
+ * buffers
+ *
+ * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx
+ */
+#define v4l2_m2m_for_each_dst_buf(m2m_ctx, b)	\
+	list_for_each_entry(b, &m2m_ctx->cap_q_ctx.rdy_queue, list)
+
+/**
+ * v4l2_m2m_for_each_src_buf() - iterate over a list of source ready buffers
+ *
+ * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx
+ */
+#define v4l2_m2m_for_each_src_buf(m2m_ctx, b)	\
+	list_for_each_entry(b, &m2m_ctx->out_q_ctx.rdy_queue, list)
+
+/**
+ * v4l2_m2m_for_each_dst_buf_safe() - iterate over a list of destination ready
+ * buffers safely
+ *
+ * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx
+ */
+#define v4l2_m2m_for_each_dst_buf_safe(m2m_ctx, b, n)	\
+	list_for_each_entry_safe(b, n, &m2m_ctx->cap_q_ctx.rdy_queue, list)
+
+/**
+ * v4l2_m2m_for_each_src_buf_safe() - iterate over a list of source ready
+ * buffers safely
+ *
+ * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx
+ */
+#define v4l2_m2m_for_each_src_buf_safe(m2m_ctx, b, n)	\
+	list_for_each_entry_safe(b, n, &m2m_ctx->out_q_ctx.rdy_queue, list)
+
+/**
  * v4l2_m2m_get_src_vq() - return vb2_queue for source buffers
  *
  * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx
@@ -488,6 +523,54 @@  static inline void *v4l2_m2m_dst_buf_remove(struct v4l2_m2m_ctx *m2m_ctx)
 	return v4l2_m2m_buf_remove(&m2m_ctx->cap_q_ctx);
 }
 
+/**
+ * v4l2_m2m_buf_remove_exact() - take off exact buffer from the list of ready
+ * buffers
+ *
+ * @q_ctx: pointer to struct @v4l2_m2m_queue_ctx
+ */
+void v4l2_m2m_buf_remove_exact(struct v4l2_m2m_queue_ctx *q_ctx,
+			       struct vb2_v4l2_buffer *vbuf);
+
+/**
+ * v4l2_m2m_src_buf_remove_exact() - take off exact source buffer from the list
+ * of ready buffers
+ *
+ * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx
+ */
+static inline void v4l2_m2m_src_buf_remove_exact(struct v4l2_m2m_ctx *m2m_ctx,
+						 struct vb2_v4l2_buffer *vbuf)
+{
+	v4l2_m2m_buf_remove_exact(&m2m_ctx->out_q_ctx, vbuf);
+}
+
+/**
+ * v4l2_m2m_src_buf_remove_exact() - take off exact destination buffer from the
+ * list of ready buffers
+ *
+ * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx
+ */
+static inline void v4l2_m2m_dst_buf_remove_exact(struct v4l2_m2m_ctx *m2m_ctx,
+						 struct vb2_v4l2_buffer *vbuf)
+{
+	v4l2_m2m_buf_remove_exact(&m2m_ctx->cap_q_ctx, vbuf);
+}
+
+struct vb2_v4l2_buffer *
+v4l2_m2m_buf_remove_by_idx(struct v4l2_m2m_queue_ctx *q_ctx, unsigned int idx);
+
+static inline struct vb2_v4l2_buffer *
+v4l2_m2m_src_buf_remove_by_idx(struct v4l2_m2m_ctx *m2m_ctx, unsigned int idx)
+{
+	return v4l2_m2m_buf_remove_by_idx(&m2m_ctx->out_q_ctx, idx);
+}
+
+static inline struct vb2_v4l2_buffer *
+v4l2_m2m_dst_buf_remove_by_idx(struct v4l2_m2m_ctx *m2m_ctx, unsigned int idx)
+{
+	return v4l2_m2m_buf_remove_by_idx(&m2m_ctx->cap_q_ctx, idx);
+}
+
 /* v4l2 ioctl helpers */
 
 int v4l2_m2m_ioctl_reqbufs(struct file *file, void *priv,