linux-media.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/2] Improve V4L2 M2M job scheduler
@ 2023-07-04  4:00 Hsia-Jun Li
  2023-07-04  4:00 ` [PATCH 1/2] [RESEND] media: v4l2-mem2mem: allow device run without buf Hsia-Jun Li
                   ` (2 more replies)
  0 siblings, 3 replies; 33+ messages in thread
From: Hsia-Jun Li @ 2023-07-04  4:00 UTC (permalink / raw)
  To: linux-media
  Cc: ayaka, hans.verkuil, tfiga, mchehab, laurent.pinchart, hiroh,
	hverkuil, linux-kernel, nicolas, Hsia-Jun(Randy) Li

From: "Hsia-Jun(Randy) Li" <randy.li@synaptics.com>

The first patch is an old patch, I resend it again.
I want to make the work thats parses the bitstream
to extract the sequence information or video resolution
as a part of V4L2 schedule. Such a work would also
consume the device's resources likes remote CPU
time.

Although reuse a flag which no current driver may
not be a good idea. I could add a new flag for that
if people like that.

The second is a patch offering a generic solution
for tracking buffers which have been pushed to
hardware(or firmware). It didn't record which buffer
that hardware(firmware) still holds for future
decoding(likes the reference buffer), while it
has been sent to the user(dequeue). We may need
a flag for this work.

Hsia-Jun(Randy) Li (1):
  media: v4l2-mem2mem: add a list for buf used by hw

Randy Li (1):
  media: v4l2-mem2mem: allow device run without buf

 drivers/media/v4l2-core/v4l2-mem2mem.c | 30 +++++++++++++++++---------
 include/media/v4l2-mem2mem.h           | 10 ++++++++-
 2 files changed, 29 insertions(+), 11 deletions(-)

-- 
2.17.1


^ permalink raw reply	[flat|nested] 33+ messages in thread

* [PATCH 1/2] [RESEND] media: v4l2-mem2mem: allow device run without buf
  2023-07-04  4:00 [PATCH 0/2] Improve V4L2 M2M job scheduler Hsia-Jun Li
@ 2023-07-04  4:00 ` Hsia-Jun Li
  2023-07-07 19:14   ` Nicolas Dufresne
  2023-07-04  4:00 ` [PATCH 2/2] media: v4l2-mem2mem: add a list for buf used by hw Hsia-Jun Li
  2023-08-18 14:45 ` [PATCH 0/2] Improve V4L2 M2M job scheduler Hans Verkuil
  2 siblings, 1 reply; 33+ messages in thread
From: Hsia-Jun Li @ 2023-07-04  4:00 UTC (permalink / raw)
  To: linux-media
  Cc: ayaka, hans.verkuil, tfiga, mchehab, laurent.pinchart, hiroh,
	hverkuil, linux-kernel, nicolas

From: Randy Li <ayaka@soulik.info>

For the decoder supports Dynamic Resolution Change,
we don't need to allocate any CAPTURE or graphics buffer
for them at inital CAPTURE setup step.

We need to make the device run or we can't get those
metadata.

Signed-off-by: Randy Li <ayaka@soulik.info>
---
 drivers/media/v4l2-core/v4l2-mem2mem.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/media/v4l2-core/v4l2-mem2mem.c b/drivers/media/v4l2-core/v4l2-mem2mem.c
index 0cc30397fbad..c771aba42015 100644
--- a/drivers/media/v4l2-core/v4l2-mem2mem.c
+++ b/drivers/media/v4l2-core/v4l2-mem2mem.c
@@ -301,8 +301,9 @@ static void __v4l2_m2m_try_queue(struct v4l2_m2m_dev *m2m_dev,
 
 	dprintk("Trying to schedule a job for m2m_ctx: %p\n", m2m_ctx);
 
-	if (!m2m_ctx->out_q_ctx.q.streaming
-	    || !m2m_ctx->cap_q_ctx.q.streaming) {
+	if (!(m2m_ctx->out_q_ctx.q.streaming || m2m_ctx->out_q_ctx.buffered)
+	    || !(m2m_ctx->cap_q_ctx.q.streaming
+		 || m2m_ctx->cap_q_ctx.buffered)) {
 		dprintk("Streaming needs to be on for both queues\n");
 		return;
 	}
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [PATCH 2/2] media: v4l2-mem2mem: add a list for buf used by hw
  2023-07-04  4:00 [PATCH 0/2] Improve V4L2 M2M job scheduler Hsia-Jun Li
  2023-07-04  4:00 ` [PATCH 1/2] [RESEND] media: v4l2-mem2mem: allow device run without buf Hsia-Jun Li
@ 2023-07-04  4:00 ` Hsia-Jun Li
  2023-07-07 19:20   ` Nicolas Dufresne
                     ` (2 more replies)
  2023-08-18 14:45 ` [PATCH 0/2] Improve V4L2 M2M job scheduler Hans Verkuil
  2 siblings, 3 replies; 33+ messages in thread
From: Hsia-Jun Li @ 2023-07-04  4:00 UTC (permalink / raw)
  To: linux-media
  Cc: ayaka, hans.verkuil, tfiga, mchehab, laurent.pinchart, hiroh,
	hverkuil, linux-kernel, nicolas, Hsia-Jun(Randy) Li

From: "Hsia-Jun(Randy) Li" <randy.li@synaptics.com>

Many drivers have to create its own buf_struct for a
vb2_queue to track such a state. Also driver has to
iterate over rdy_queue every times to find out a buffer
which is not sent to hardware(or firmware), this new
list just offers the driver a place to store the buffer
that hardware(firmware) has acknowledged.

One important advance about this list, it doesn't like
rdy_queue which both bottom half of the user calling
could operate it, while the v4l2 worker would as well.
The v4l2 core could only operate this queue when its
v4l2_context is not running, the driver would only
access this new hw_queue in its own worker.

Signed-off-by: Hsia-Jun(Randy) Li <randy.li@synaptics.com>
---
 drivers/media/v4l2-core/v4l2-mem2mem.c | 25 +++++++++++++++++--------
 include/media/v4l2-mem2mem.h           | 10 +++++++++-
 2 files changed, 26 insertions(+), 9 deletions(-)

diff --git a/drivers/media/v4l2-core/v4l2-mem2mem.c b/drivers/media/v4l2-core/v4l2-mem2mem.c
index c771aba42015..b4151147d5bd 100644
--- a/drivers/media/v4l2-core/v4l2-mem2mem.c
+++ b/drivers/media/v4l2-core/v4l2-mem2mem.c
@@ -321,15 +321,21 @@ static void __v4l2_m2m_try_queue(struct v4l2_m2m_dev *m2m_dev,
 		goto job_unlock;
 	}
 
-	src = v4l2_m2m_next_src_buf(m2m_ctx);
-	dst = v4l2_m2m_next_dst_buf(m2m_ctx);
-	if (!src && !m2m_ctx->out_q_ctx.buffered) {
-		dprintk("No input buffers available\n");
-		goto job_unlock;
+	if (list_empty(&m2m_ctx->out_q_ctx.hw_queue)) {
+		src = v4l2_m2m_next_src_buf(m2m_ctx);
+
+		if (!src && !m2m_ctx->out_q_ctx.buffered) {
+			dprintk("No input buffers available\n");
+			goto job_unlock;
+		}
 	}
-	if (!dst && !m2m_ctx->cap_q_ctx.buffered) {
-		dprintk("No output buffers available\n");
-		goto job_unlock;
+
+	if (list_empty(&m2m_ctx->cap_q_ctx.hw_queue)) {
+		dst = v4l2_m2m_next_dst_buf(m2m_ctx);
+		if (!dst && !m2m_ctx->cap_q_ctx.buffered) {
+			dprintk("No output buffers available\n");
+			goto job_unlock;
+		}
 	}
 
 	m2m_ctx->new_frame = true;
@@ -896,6 +902,7 @@ int v4l2_m2m_streamoff(struct file *file, struct v4l2_m2m_ctx *m2m_ctx,
 	INIT_LIST_HEAD(&q_ctx->rdy_queue);
 	q_ctx->num_rdy = 0;
 	spin_unlock_irqrestore(&q_ctx->rdy_spinlock, flags);
+	INIT_LIST_HEAD(&q_ctx->hw_queue);
 
 	if (m2m_dev->curr_ctx == m2m_ctx) {
 		m2m_dev->curr_ctx = NULL;
@@ -1234,6 +1241,8 @@ struct v4l2_m2m_ctx *v4l2_m2m_ctx_init(struct v4l2_m2m_dev *m2m_dev,
 
 	INIT_LIST_HEAD(&out_q_ctx->rdy_queue);
 	INIT_LIST_HEAD(&cap_q_ctx->rdy_queue);
+	INIT_LIST_HEAD(&out_q_ctx->hw_queue);
+	INIT_LIST_HEAD(&cap_q_ctx->hw_queue);
 	spin_lock_init(&out_q_ctx->rdy_spinlock);
 	spin_lock_init(&cap_q_ctx->rdy_spinlock);
 
diff --git a/include/media/v4l2-mem2mem.h b/include/media/v4l2-mem2mem.h
index d6c8eb2b5201..2342656e582d 100644
--- a/include/media/v4l2-mem2mem.h
+++ b/include/media/v4l2-mem2mem.h
@@ -53,9 +53,16 @@ struct v4l2_m2m_dev;
  *	processed
  *
  * @q:		pointer to struct &vb2_queue
- * @rdy_queue:	List of V4L2 mem-to-mem queues
+ * @rdy_queue:	List of V4L2 mem-to-mem queues. If v4l2_m2m_buf_queue() is
+ *		called in struct vb2_ops->buf_queue(), the buffer enqueued
+ *		by user would be added to this list.
  * @rdy_spinlock: spin lock to protect the struct usage
  * @num_rdy:	number of buffers ready to be processed
+ * @hw_queue:	A list for tracking the buffer is occupied by the hardware
+ * 		(or device's firmware). A buffer could only be in either
+ * 		this list or @rdy_queue.
+ * 		Driver may choose not to use this list while uses its own
+ * 		private data to do this work.
  * @buffered:	is the queue buffered?
  *
  * Queue for buffers ready to be processed as soon as this
@@ -68,6 +75,7 @@ struct v4l2_m2m_queue_ctx {
 	struct list_head	rdy_queue;
 	spinlock_t		rdy_spinlock;
 	u8			num_rdy;
+	struct list_head	hw_queue;
 	bool			buffered;
 };
 
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 33+ messages in thread

* Re: [PATCH 1/2] [RESEND] media: v4l2-mem2mem: allow device run without buf
  2023-07-04  4:00 ` [PATCH 1/2] [RESEND] media: v4l2-mem2mem: allow device run without buf Hsia-Jun Li
@ 2023-07-07 19:14   ` Nicolas Dufresne
  2023-07-12  9:31     ` Tomasz Figa
  0 siblings, 1 reply; 33+ messages in thread
From: Nicolas Dufresne @ 2023-07-07 19:14 UTC (permalink / raw)
  To: Hsia-Jun Li, linux-media
  Cc: ayaka, hans.verkuil, tfiga, mchehab, laurent.pinchart, hiroh,
	hverkuil, linux-kernel, Sebastian Fricke

Hi Randy,

Le mardi 04 juillet 2023 à 12:00 +0800, Hsia-Jun Li a écrit :
> From: Randy Li <ayaka@soulik.info>
> 
> For the decoder supports Dynamic Resolution Change,
> we don't need to allocate any CAPTURE or graphics buffer
> for them at inital CAPTURE setup step.
> 
> We need to make the device run or we can't get those
> metadata.
> 
> Signed-off-by: Randy Li <ayaka@soulik.info>
> ---
>  drivers/media/v4l2-core/v4l2-mem2mem.c | 5 +++--
>  1 file changed, 3 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/media/v4l2-core/v4l2-mem2mem.c b/drivers/media/v4l2-core/v4l2-mem2mem.c
> index 0cc30397fbad..c771aba42015 100644
> --- a/drivers/media/v4l2-core/v4l2-mem2mem.c
> +++ b/drivers/media/v4l2-core/v4l2-mem2mem.c
> @@ -301,8 +301,9 @@ static void __v4l2_m2m_try_queue(struct v4l2_m2m_dev *m2m_dev,
>  
>  	dprintk("Trying to schedule a job for m2m_ctx: %p\n", m2m_ctx);
>  
> -	if (!m2m_ctx->out_q_ctx.q.streaming
> -	    || !m2m_ctx->cap_q_ctx.q.streaming) {
> +	if (!(m2m_ctx->out_q_ctx.q.streaming || m2m_ctx->out_q_ctx.buffered)
> +	    || !(m2m_ctx->cap_q_ctx.q.streaming
> +		 || m2m_ctx->cap_q_ctx.buffered)) {

I have a two atches with similar goals in my wave5 tree. It will be easier to
upstream with an actual user, though, I'm probably a month or two away from
submitting this driver again.

https://gitlab.collabora.com/chipsnmedia/kernel/-/commit/ac59eafd5076c4deb3bfe1fb85b3b776586ef3eb
https://gitlab.collabora.com/chipsnmedia/kernel/-/commit/5de4fbe0abb20b8e8d862b654f93e3efeb1ef251

Sebastien and I authored this without giving it much thought, but we believe
this massively simplify our handling of DRC (dynamic resolution change).

The main difference, is that we added ignore_streaming to the ctx, so that
drivers can opt-in the mode of operation. Thinking it would avoid any potential
side effects in drivers that aren't prepared to that. We didn't want to tied it
up to buffered, this is open to discussion of course, we do use buffered on both
queues and use a slightly more advance job_ready function, that take into
account our driver state.

In short, Sebastien and I agree this small change is the right direction, we
simply have a different implementation. I can send it as RFC if one believe its
would be useful now (even without a user).

>  		dprintk("Streaming needs to be on for both queues\n");
>  		return;
>  	}


^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH 2/2] media: v4l2-mem2mem: add a list for buf used by hw
  2023-07-04  4:00 ` [PATCH 2/2] media: v4l2-mem2mem: add a list for buf used by hw Hsia-Jun Li
@ 2023-07-07 19:20   ` Nicolas Dufresne
  2023-07-11  8:54     ` Randy Li
  2023-07-11  6:26   ` Dan Carpenter
  2023-07-12  9:33   ` Tomasz Figa
  2 siblings, 1 reply; 33+ messages in thread
From: Nicolas Dufresne @ 2023-07-07 19:20 UTC (permalink / raw)
  To: Hsia-Jun Li, linux-media
  Cc: ayaka, hans.verkuil, tfiga, mchehab, laurent.pinchart, hiroh,
	hverkuil, linux-kernel

Le mardi 04 juillet 2023 à 12:00 +0800, Hsia-Jun Li a écrit :
> From: "Hsia-Jun(Randy) Li" <randy.li@synaptics.com>
> 
> Many drivers have to create its own buf_struct for a
> vb2_queue to track such a state. Also driver has to
> iterate over rdy_queue every times to find out a buffer
> which is not sent to hardware(or firmware), this new
> list just offers the driver a place to store the buffer
> that hardware(firmware) has acknowledged.
> 
> One important advance about this list, it doesn't like
> rdy_queue which both bottom half of the user calling
> could operate it, while the v4l2 worker would as well.
> The v4l2 core could only operate this queue when its
> v4l2_context is not running, the driver would only
> access this new hw_queue in its own worker.

That's an interesting proposal. I didn't like leaving decoded frames into the
rdy_queue, but removing them required me to have my own list, so that I can
clean it up if some buffers are never displayed.

We'll see if we can use this into wave5.

> 
> Signed-off-by: Hsia-Jun(Randy) Li <randy.li@synaptics.com>
> ---
>  drivers/media/v4l2-core/v4l2-mem2mem.c | 25 +++++++++++++++++--------
>  include/media/v4l2-mem2mem.h           | 10 +++++++++-
>  2 files changed, 26 insertions(+), 9 deletions(-)
> 
> diff --git a/drivers/media/v4l2-core/v4l2-mem2mem.c b/drivers/media/v4l2-core/v4l2-mem2mem.c
> index c771aba42015..b4151147d5bd 100644
> --- a/drivers/media/v4l2-core/v4l2-mem2mem.c
> +++ b/drivers/media/v4l2-core/v4l2-mem2mem.c
> @@ -321,15 +321,21 @@ static void __v4l2_m2m_try_queue(struct v4l2_m2m_dev *m2m_dev,
>  		goto job_unlock;
>  	}
>  
> -	src = v4l2_m2m_next_src_buf(m2m_ctx);
> -	dst = v4l2_m2m_next_dst_buf(m2m_ctx);
> -	if (!src && !m2m_ctx->out_q_ctx.buffered) {
> -		dprintk("No input buffers available\n");
> -		goto job_unlock;
> +	if (list_empty(&m2m_ctx->out_q_ctx.hw_queue)) {
> +		src = v4l2_m2m_next_src_buf(m2m_ctx);
> +
> +		if (!src && !m2m_ctx->out_q_ctx.buffered) {
> +			dprintk("No input buffers available\n");
> +			goto job_unlock;
> +		}
>  	}
> -	if (!dst && !m2m_ctx->cap_q_ctx.buffered) {
> -		dprintk("No output buffers available\n");
> -		goto job_unlock;
> +
> +	if (list_empty(&m2m_ctx->cap_q_ctx.hw_queue)) {
> +		dst = v4l2_m2m_next_dst_buf(m2m_ctx);
> +		if (!dst && !m2m_ctx->cap_q_ctx.buffered) {
> +			dprintk("No output buffers available\n");
> +			goto job_unlock;
> +		}
>  	}
>  
>  	m2m_ctx->new_frame = true;
> @@ -896,6 +902,7 @@ int v4l2_m2m_streamoff(struct file *file, struct v4l2_m2m_ctx *m2m_ctx,
>  	INIT_LIST_HEAD(&q_ctx->rdy_queue);
>  	q_ctx->num_rdy = 0;
>  	spin_unlock_irqrestore(&q_ctx->rdy_spinlock, flags);
> +	INIT_LIST_HEAD(&q_ctx->hw_queue);
>  
>  	if (m2m_dev->curr_ctx == m2m_ctx) {
>  		m2m_dev->curr_ctx = NULL;
> @@ -1234,6 +1241,8 @@ struct v4l2_m2m_ctx *v4l2_m2m_ctx_init(struct v4l2_m2m_dev *m2m_dev,
>  
>  	INIT_LIST_HEAD(&out_q_ctx->rdy_queue);
>  	INIT_LIST_HEAD(&cap_q_ctx->rdy_queue);
> +	INIT_LIST_HEAD(&out_q_ctx->hw_queue);
> +	INIT_LIST_HEAD(&cap_q_ctx->hw_queue);
>  	spin_lock_init(&out_q_ctx->rdy_spinlock);
>  	spin_lock_init(&cap_q_ctx->rdy_spinlock);
>  
> diff --git a/include/media/v4l2-mem2mem.h b/include/media/v4l2-mem2mem.h
> index d6c8eb2b5201..2342656e582d 100644
> --- a/include/media/v4l2-mem2mem.h
> +++ b/include/media/v4l2-mem2mem.h
> @@ -53,9 +53,16 @@ struct v4l2_m2m_dev;
>   *	processed
>   *
>   * @q:		pointer to struct &vb2_queue
> - * @rdy_queue:	List of V4L2 mem-to-mem queues
> + * @rdy_queue:	List of V4L2 mem-to-mem queues. If v4l2_m2m_buf_queue() is
> + *		called in struct vb2_ops->buf_queue(), the buffer enqueued
> + *		by user would be added to this list.
>   * @rdy_spinlock: spin lock to protect the struct usage
>   * @num_rdy:	number of buffers ready to be processed
> + * @hw_queue:	A list for tracking the buffer is occupied by the hardware
> + * 		(or device's firmware). A buffer could only be in either
> + * 		this list or @rdy_queue.
> + * 		Driver may choose not to use this list while uses its own
> + * 		private data to do this work.

What's the threading protection around this one ? Also, would it be possible to
opt-in that the driver cleanup that list automatically after streamoff has been
executed ?

One thing the doc is missing, is that HW buffer are actually flagged as ACTIVE
buffer vb2, there is a strong link between the two concept, and the doc should
take care.

>   * @buffered:	is the queue buffered?
>   *
>   * Queue for buffers ready to be processed as soon as this
> @@ -68,6 +75,7 @@ struct v4l2_m2m_queue_ctx {
>  	struct list_head	rdy_queue;
>  	spinlock_t		rdy_spinlock;
>  	u8			num_rdy;
> +	struct list_head	hw_queue;
>  	bool			buffered;
>  };
>  


^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH 2/2] media: v4l2-mem2mem: add a list for buf used by hw
  2023-07-04  4:00 ` [PATCH 2/2] media: v4l2-mem2mem: add a list for buf used by hw Hsia-Jun Li
  2023-07-07 19:20   ` Nicolas Dufresne
@ 2023-07-11  6:26   ` Dan Carpenter
  2023-07-12  9:33   ` Tomasz Figa
  2 siblings, 0 replies; 33+ messages in thread
From: Dan Carpenter @ 2023-07-11  6:26 UTC (permalink / raw)
  To: oe-kbuild, Hsia-Jun Li, linux-media
  Cc: lkp, oe-kbuild-all, ayaka, hans.verkuil, tfiga, mchehab,
	laurent.pinchart, hiroh, hverkuil, linux-kernel, nicolas,
	Hsia-Jun(Randy) Li

Hi Hsia-Jun,

kernel test robot noticed the following build warnings:

https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Hsia-Jun-Li/media-v4l2-mem2mem-allow-device-run-without-buf/20230704-120308
base:   git://linuxtv.org/media_tree.git master
patch link:    https://lore.kernel.org/r/20230704040044.681850-3-randy.li%40synaptics.com
patch subject: [PATCH 2/2] media: v4l2-mem2mem: add a list for buf used by hw
config: arm64-randconfig-m041-20230710 (https://download.01.org/0day-ci/archive/20230711/202307110324.A5LMPHou-lkp@intel.com/config)
compiler: aarch64-linux-gcc (GCC) 12.3.0
reproduce: (https://download.01.org/0day-ci/archive/20230711/202307110324.A5LMPHou-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Reported-by: Dan Carpenter <dan.carpenter@linaro.org>
| Closes: https://lore.kernel.org/r/202307110324.A5LMPHou-lkp@intel.com/

smatch warnings:
drivers/media/v4l2-core/v4l2-mem2mem.c:343 __v4l2_m2m_try_queue() error: uninitialized symbol 'src'.
drivers/media/v4l2-core/v4l2-mem2mem.c:343 __v4l2_m2m_try_queue() error: uninitialized symbol 'dst'.

vim +/src +343 drivers/media/v4l2-core/v4l2-mem2mem.c

9db3bbf58be59a drivers/media/v4l2-core/v4l2-mem2mem.c Ezequiel Garcia    2018-07-25  296  static void __v4l2_m2m_try_queue(struct v4l2_m2m_dev *m2m_dev,
9db3bbf58be59a drivers/media/v4l2-core/v4l2-mem2mem.c Ezequiel Garcia    2018-07-25  297  				 struct v4l2_m2m_ctx *m2m_ctx)
7f98639def42a6 drivers/media/video/v4l2-mem2mem.c     Pawel Osciak       2010-04-23  298  {
f8cca8c97a63d7 drivers/media/v4l2-core/v4l2-mem2mem.c Hans Verkuil       2019-10-11  299  	unsigned long flags_job;
f8cca8c97a63d7 drivers/media/v4l2-core/v4l2-mem2mem.c Hans Verkuil       2019-10-11  300  	struct vb2_v4l2_buffer *dst, *src;
7f98639def42a6 drivers/media/video/v4l2-mem2mem.c     Pawel Osciak       2010-04-23  301  
7f98639def42a6 drivers/media/video/v4l2-mem2mem.c     Pawel Osciak       2010-04-23  302  	dprintk("Trying to schedule a job for m2m_ctx: %p\n", m2m_ctx);
7f98639def42a6 drivers/media/video/v4l2-mem2mem.c     Pawel Osciak       2010-04-23  303  
f3e1a4c9d7a02d drivers/media/v4l2-core/v4l2-mem2mem.c Randy Li           2023-07-04  304  	if (!(m2m_ctx->out_q_ctx.q.streaming || m2m_ctx->out_q_ctx.buffered)
f3e1a4c9d7a02d drivers/media/v4l2-core/v4l2-mem2mem.c Randy Li           2023-07-04  305  	    || !(m2m_ctx->cap_q_ctx.q.streaming
f3e1a4c9d7a02d drivers/media/v4l2-core/v4l2-mem2mem.c Randy Li           2023-07-04  306  		 || m2m_ctx->cap_q_ctx.buffered)) {
7f98639def42a6 drivers/media/video/v4l2-mem2mem.c     Pawel Osciak       2010-04-23  307  		dprintk("Streaming needs to be on for both queues\n");
7f98639def42a6 drivers/media/video/v4l2-mem2mem.c     Pawel Osciak       2010-04-23  308  		return;
7f98639def42a6 drivers/media/video/v4l2-mem2mem.c     Pawel Osciak       2010-04-23  309  	}
7f98639def42a6 drivers/media/video/v4l2-mem2mem.c     Pawel Osciak       2010-04-23  310  
7f98639def42a6 drivers/media/video/v4l2-mem2mem.c     Pawel Osciak       2010-04-23  311  	spin_lock_irqsave(&m2m_dev->job_spinlock, flags_job);
2ad5389b341282 drivers/media/v4l2-core/v4l2-mem2mem.c Shaik Ameer Basha  2013-09-20  312  
2ad5389b341282 drivers/media/v4l2-core/v4l2-mem2mem.c Shaik Ameer Basha  2013-09-20  313  	/* If the context is aborted then don't schedule it */
2ad5389b341282 drivers/media/v4l2-core/v4l2-mem2mem.c Shaik Ameer Basha  2013-09-20  314  	if (m2m_ctx->job_flags & TRANS_ABORT) {
2ad5389b341282 drivers/media/v4l2-core/v4l2-mem2mem.c Shaik Ameer Basha  2013-09-20  315  		dprintk("Aborted context\n");
cbec2836f8be61 drivers/media/v4l2-core/v4l2-mem2mem.c Sakari Ailus       2018-10-18  316  		goto job_unlock;
2ad5389b341282 drivers/media/v4l2-core/v4l2-mem2mem.c Shaik Ameer Basha  2013-09-20  317  	}
2ad5389b341282 drivers/media/v4l2-core/v4l2-mem2mem.c Shaik Ameer Basha  2013-09-20  318  
7f98639def42a6 drivers/media/video/v4l2-mem2mem.c     Pawel Osciak       2010-04-23  319  	if (m2m_ctx->job_flags & TRANS_QUEUED) {
7f98639def42a6 drivers/media/video/v4l2-mem2mem.c     Pawel Osciak       2010-04-23  320  		dprintk("On job queue already\n");
cbec2836f8be61 drivers/media/v4l2-core/v4l2-mem2mem.c Sakari Ailus       2018-10-18  321  		goto job_unlock;
7f98639def42a6 drivers/media/video/v4l2-mem2mem.c     Pawel Osciak       2010-04-23  322  	}
7f98639def42a6 drivers/media/video/v4l2-mem2mem.c     Pawel Osciak       2010-04-23  323  
cafbe530b02613 drivers/media/v4l2-core/v4l2-mem2mem.c Hsia-Jun(Randy  Li 2023-07-04  324) 	if (list_empty(&m2m_ctx->out_q_ctx.hw_queue)) {
f8cca8c97a63d7 drivers/media/v4l2-core/v4l2-mem2mem.c Hans Verkuil       2019-10-11  325  		src = v4l2_m2m_next_src_buf(m2m_ctx);
cafbe530b02613 drivers/media/v4l2-core/v4l2-mem2mem.c Hsia-Jun(Randy  Li 2023-07-04  326) 
f8cca8c97a63d7 drivers/media/v4l2-core/v4l2-mem2mem.c Hans Verkuil       2019-10-11  327  		if (!src && !m2m_ctx->out_q_ctx.buffered) {
7f98639def42a6 drivers/media/video/v4l2-mem2mem.c     Pawel Osciak       2010-04-23  328  			dprintk("No input buffers available\n");
f8cca8c97a63d7 drivers/media/v4l2-core/v4l2-mem2mem.c Hans Verkuil       2019-10-11  329  			goto job_unlock;
7f98639def42a6 drivers/media/video/v4l2-mem2mem.c     Pawel Osciak       2010-04-23  330  		}
cafbe530b02613 drivers/media/v4l2-core/v4l2-mem2mem.c Hsia-Jun(Randy  Li 2023-07-04  331) 	}

src uninitialized on else path.

cafbe530b02613 drivers/media/v4l2-core/v4l2-mem2mem.c Hsia-Jun(Randy  Li 2023-07-04  332) 
cafbe530b02613 drivers/media/v4l2-core/v4l2-mem2mem.c Hsia-Jun(Randy  Li 2023-07-04  333) 	if (list_empty(&m2m_ctx->cap_q_ctx.hw_queue)) {
cafbe530b02613 drivers/media/v4l2-core/v4l2-mem2mem.c Hsia-Jun(Randy  Li 2023-07-04  334) 		dst = v4l2_m2m_next_dst_buf(m2m_ctx);
f8cca8c97a63d7 drivers/media/v4l2-core/v4l2-mem2mem.c Hans Verkuil       2019-10-11  335  		if (!dst && !m2m_ctx->cap_q_ctx.buffered) {
7f98639def42a6 drivers/media/video/v4l2-mem2mem.c     Pawel Osciak       2010-04-23  336  			dprintk("No output buffers available\n");
f8cca8c97a63d7 drivers/media/v4l2-core/v4l2-mem2mem.c Hans Verkuil       2019-10-11  337  			goto job_unlock;
f8cca8c97a63d7 drivers/media/v4l2-core/v4l2-mem2mem.c Hans Verkuil       2019-10-11  338  		}
cafbe530b02613 drivers/media/v4l2-core/v4l2-mem2mem.c Hsia-Jun(Randy  Li 2023-07-04  339) 	}

dst not initialized if !list_empty()

f8cca8c97a63d7 drivers/media/v4l2-core/v4l2-mem2mem.c Hans Verkuil       2019-10-11  340  
f07602ac388723 drivers/media/v4l2-core/v4l2-mem2mem.c Hans Verkuil       2019-10-11  341  	m2m_ctx->new_frame = true;
f07602ac388723 drivers/media/v4l2-core/v4l2-mem2mem.c Hans Verkuil       2019-10-11  342  
f07602ac388723 drivers/media/v4l2-core/v4l2-mem2mem.c Hans Verkuil       2019-10-11 @343  	if (src && dst && dst->is_held &&

Uninitialized.

f07602ac388723 drivers/media/v4l2-core/v4l2-mem2mem.c Hans Verkuil       2019-10-11  344  	    dst->vb2_buf.copied_timestamp &&
f8cca8c97a63d7 drivers/media/v4l2-core/v4l2-mem2mem.c Hans Verkuil       2019-10-11  345  	    dst->vb2_buf.timestamp != src->vb2_buf.timestamp) {
86ef61ad686c17 drivers/media/v4l2-core/v4l2-mem2mem.c Nicolas Dufresne   2022-04-26  346  		dprintk("Timestamp mismatch, returning held capture buffer\n");
f8cca8c97a63d7 drivers/media/v4l2-core/v4l2-mem2mem.c Hans Verkuil       2019-10-11  347  		dst->is_held = false;
f8cca8c97a63d7 drivers/media/v4l2-core/v4l2-mem2mem.c Hans Verkuil       2019-10-11  348  		v4l2_m2m_dst_buf_remove(m2m_ctx);
f8cca8c97a63d7 drivers/media/v4l2-core/v4l2-mem2mem.c Hans Verkuil       2019-10-11  349  		v4l2_m2m_buf_done(dst, VB2_BUF_STATE_DONE);
f8cca8c97a63d7 drivers/media/v4l2-core/v4l2-mem2mem.c Hans Verkuil       2019-10-11  350  		dst = v4l2_m2m_next_dst_buf(m2m_ctx);
f8cca8c97a63d7 drivers/media/v4l2-core/v4l2-mem2mem.c Hans Verkuil       2019-10-11  351  
f8cca8c97a63d7 drivers/media/v4l2-core/v4l2-mem2mem.c Hans Verkuil       2019-10-11  352  		if (!dst && !m2m_ctx->cap_q_ctx.buffered) {

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki


^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH 2/2] media: v4l2-mem2mem: add a list for buf used by hw
  2023-07-07 19:20   ` Nicolas Dufresne
@ 2023-07-11  8:54     ` Randy Li
  0 siblings, 0 replies; 33+ messages in thread
From: Randy Li @ 2023-07-11  8:54 UTC (permalink / raw)
  To: Nicolas Dufresne
  Cc: hans.verkuil, tfiga, linux-media, Hsia-Jun Li, mchehab,
	laurent.pinchart, hiroh, hverkuil, linux-kernel


On 2023/7/8 03:20, Nicolas Dufresne wrote:
> Le mardi 04 juillet 2023 à 12:00 +0800, Hsia-Jun Li a écrit :
>> From: "Hsia-Jun(Randy) Li" <randy.li@synaptics.com>
>>
>> Many drivers have to create its own buf_struct for a
>> vb2_queue to track such a state. Also driver has to
>> iterate over rdy_queue every times to find out a buffer
>> which is not sent to hardware(or firmware), this new
>> list just offers the driver a place to store the buffer
>> that hardware(firmware) has acknowledged.
>>
>> One important advance about this list, it doesn't like
>> rdy_queue which both bottom half of the user calling
>> could operate it, while the v4l2 worker would as well.
>> The v4l2 core could only operate this queue when its
>> v4l2_context is not running, the driver would only
>> access this new hw_queue in its own worker.
> That's an interesting proposal. I didn't like leaving decoded frames into the
> rdy_queue, but removing them required me to have my own list, so that I can
> clean it up if some buffers are never displayed.
>
> We'll see if we can use this into wave5.
>
>> Signed-off-by: Hsia-Jun(Randy) Li <randy.li@synaptics.com>
>> ---
>>   drivers/media/v4l2-core/v4l2-mem2mem.c | 25 +++++++++++++++++--------
>>   include/media/v4l2-mem2mem.h           | 10 +++++++++-
>>   2 files changed, 26 insertions(+), 9 deletions(-)
>>
>> diff --git a/drivers/media/v4l2-core/v4l2-mem2mem.c b/drivers/media/v4l2-core/v4l2-mem2mem.c
>> index c771aba42015..b4151147d5bd 100644
>> --- a/drivers/media/v4l2-core/v4l2-mem2mem.c
>> +++ b/drivers/media/v4l2-core/v4l2-mem2mem.c
>> @@ -321,15 +321,21 @@ static void __v4l2_m2m_try_queue(struct v4l2_m2m_dev *m2m_dev,
>>   		goto job_unlock;
>>   	}
>>   
>> -	src = v4l2_m2m_next_src_buf(m2m_ctx);
>> -	dst = v4l2_m2m_next_dst_buf(m2m_ctx);
>> -	if (!src && !m2m_ctx->out_q_ctx.buffered) {
>> -		dprintk("No input buffers available\n");
>> -		goto job_unlock;
>> +	if (list_empty(&m2m_ctx->out_q_ctx.hw_queue)) {
>> +		src = v4l2_m2m_next_src_buf(m2m_ctx);
>> +
>> +		if (!src && !m2m_ctx->out_q_ctx.buffered) {
>> +			dprintk("No input buffers available\n");
>> +			goto job_unlock;
>> +		}
>>   	}
>> -	if (!dst && !m2m_ctx->cap_q_ctx.buffered) {
>> -		dprintk("No output buffers available\n");
>> -		goto job_unlock;
>> +
>> +	if (list_empty(&m2m_ctx->cap_q_ctx.hw_queue)) {
>> +		dst = v4l2_m2m_next_dst_buf(m2m_ctx);
>> +		if (!dst && !m2m_ctx->cap_q_ctx.buffered) {
>> +			dprintk("No output buffers available\n");
>> +			goto job_unlock;
>> +		}
>>   	}
>>   
>>   	m2m_ctx->new_frame = true;
>> @@ -896,6 +902,7 @@ int v4l2_m2m_streamoff(struct file *file, struct v4l2_m2m_ctx *m2m_ctx,
>>   	INIT_LIST_HEAD(&q_ctx->rdy_queue);
>>   	q_ctx->num_rdy = 0;
>>   	spin_unlock_irqrestore(&q_ctx->rdy_spinlock, flags);
>> +	INIT_LIST_HEAD(&q_ctx->hw_queue);
>>   
>>   	if (m2m_dev->curr_ctx == m2m_ctx) {
>>   		m2m_dev->curr_ctx = NULL;
>> @@ -1234,6 +1241,8 @@ struct v4l2_m2m_ctx *v4l2_m2m_ctx_init(struct v4l2_m2m_dev *m2m_dev,
>>   
>>   	INIT_LIST_HEAD(&out_q_ctx->rdy_queue);
>>   	INIT_LIST_HEAD(&cap_q_ctx->rdy_queue);
>> +	INIT_LIST_HEAD(&out_q_ctx->hw_queue);
>> +	INIT_LIST_HEAD(&cap_q_ctx->hw_queue);
>>   	spin_lock_init(&out_q_ctx->rdy_spinlock);
>>   	spin_lock_init(&cap_q_ctx->rdy_spinlock);
>>   
>> diff --git a/include/media/v4l2-mem2mem.h b/include/media/v4l2-mem2mem.h
>> index d6c8eb2b5201..2342656e582d 100644
>> --- a/include/media/v4l2-mem2mem.h
>> +++ b/include/media/v4l2-mem2mem.h
>> @@ -53,9 +53,16 @@ struct v4l2_m2m_dev;
>>    *	processed
>>    *
>>    * @q:		pointer to struct &vb2_queue
>> - * @rdy_queue:	List of V4L2 mem-to-mem queues
>> + * @rdy_queue:	List of V4L2 mem-to-mem queues. If v4l2_m2m_buf_queue() is
>> + *		called in struct vb2_ops->buf_queue(), the buffer enqueued
>> + *		by user would be added to this list.
>>    * @rdy_spinlock: spin lock to protect the struct usage
>>    * @num_rdy:	number of buffers ready to be processed
>> + * @hw_queue:	A list for tracking the buffer is occupied by the hardware
>> + * 		(or device's firmware). A buffer could only be in either
>> + * 		this list or @rdy_queue.
>> + * 		Driver may choose not to use this list while uses its own
>> + * 		private data to do this work.
> What's the threading protection around this one ?

I mentioned that in commit message.

"

The v4l2 core could only operate this queue when its
v4l2_context is not running, the driver would only
access this new hw_queue in its own worker.
"

>   Also, would it be possible to
> opt-in that the driver cleanup that list automatically after streamoff has been
> executed ?
I think that is what streamoff purposes to do, or we don't have a method 
to let the hardware(firmware) release all its buffers.
>
> One thing the doc is missing, is that HW buffer are actually flagged as ACTIVE
> buffer vb2, there is a strong link between the two concept, and the doc should
> take care.

I would like to complete the doc if people are not against about this idea.

And I would put all necessary information in one place.

>
>>    * @buffered:	is the queue buffered?
>>    *
>>    * Queue for buffers ready to be processed as soon as this
>> @@ -68,6 +75,7 @@ struct v4l2_m2m_queue_ctx {
>>   	struct list_head	rdy_queue;
>>   	spinlock_t		rdy_spinlock;
>>   	u8			num_rdy;
>> +	struct list_head	hw_queue;
>>   	bool			buffered;
>>   };
>>   

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH 1/2] [RESEND] media: v4l2-mem2mem: allow device run without buf
  2023-07-07 19:14   ` Nicolas Dufresne
@ 2023-07-12  9:31     ` Tomasz Figa
  2023-07-12  9:44       ` Sebastian Fricke
  2023-07-17 14:00       ` Nicolas Dufresne
  0 siblings, 2 replies; 33+ messages in thread
From: Tomasz Figa @ 2023-07-12  9:31 UTC (permalink / raw)
  To: Nicolas Dufresne
  Cc: Hsia-Jun Li, linux-media, ayaka, hans.verkuil, mchehab,
	laurent.pinchart, hiroh, hverkuil, linux-kernel,
	Sebastian Fricke

On Fri, Jul 07, 2023 at 03:14:23PM -0400, Nicolas Dufresne wrote:
> Hi Randy,
> 
> Le mardi 04 juillet 2023 à 12:00 +0800, Hsia-Jun Li a écrit :
> > From: Randy Li <ayaka@soulik.info>
> > 
> > For the decoder supports Dynamic Resolution Change,
> > we don't need to allocate any CAPTURE or graphics buffer
> > for them at inital CAPTURE setup step.
> > 
> > We need to make the device run or we can't get those
> > metadata.
> > 
> > Signed-off-by: Randy Li <ayaka@soulik.info>
> > ---
> >  drivers/media/v4l2-core/v4l2-mem2mem.c | 5 +++--
> >  1 file changed, 3 insertions(+), 2 deletions(-)
> > 
> > diff --git a/drivers/media/v4l2-core/v4l2-mem2mem.c b/drivers/media/v4l2-core/v4l2-mem2mem.c
> > index 0cc30397fbad..c771aba42015 100644
> > --- a/drivers/media/v4l2-core/v4l2-mem2mem.c
> > +++ b/drivers/media/v4l2-core/v4l2-mem2mem.c
> > @@ -301,8 +301,9 @@ static void __v4l2_m2m_try_queue(struct v4l2_m2m_dev *m2m_dev,
> >  
> >  	dprintk("Trying to schedule a job for m2m_ctx: %p\n", m2m_ctx);
> >  
> > -	if (!m2m_ctx->out_q_ctx.q.streaming
> > -	    || !m2m_ctx->cap_q_ctx.q.streaming) {
> > +	if (!(m2m_ctx->out_q_ctx.q.streaming || m2m_ctx->out_q_ctx.buffered)
> > +	    || !(m2m_ctx->cap_q_ctx.q.streaming
> > +		 || m2m_ctx->cap_q_ctx.buffered)) {
> 
> I have a two atches with similar goals in my wave5 tree. It will be easier to
> upstream with an actual user, though, I'm probably a month or two away from
> submitting this driver again.
> 
> https://gitlab.collabora.com/chipsnmedia/kernel/-/commit/ac59eafd5076c4deb3bfe1fb85b3b776586ef3eb
> https://gitlab.collabora.com/chipsnmedia/kernel/-/commit/5de4fbe0abb20b8e8d862b654f93e3efeb1ef251
> 

While I'm not going to NAK this series or those 2 patches if you send
them, I'm not really convinced that adding more and more complexity to
the mem2mem helpers is a good idea, especially since all of those seem
to be only needed by stateful video decoders.

The mem2mem framework started as a set of helpers to eliminate boiler
plate from simple drivers that always get 1 CAPTURE and 1 OUTPUT buffer,
run 1 processing job on them and then return both of the to the userspace
and I think it should stay like this.

I think we're strongly in need of a stateful video decoder framework that
would actually address the exact problems that those have rather than
bending something that wasn't designed with them in mind to work around the
differences.

Best regards,
Tomasz

> Sebastien and I authored this without giving it much thought, but we believe
> this massively simplify our handling of DRC (dynamic resolution change).
> 
> The main difference, is that we added ignore_streaming to the ctx, so that
> drivers can opt-in the mode of operation. Thinking it would avoid any potential
> side effects in drivers that aren't prepared to that. We didn't want to tied it
> up to buffered, this is open to discussion of course, we do use buffered on both
> queues and use a slightly more advance job_ready function, that take into
> account our driver state.
> 
> In short, Sebastien and I agree this small change is the right direction, we
> simply have a different implementation. I can send it as RFC if one believe its
> would be useful now (even without a user).
> 
> >  		dprintk("Streaming needs to be on for both queues\n");
> >  		return;
> >  	}
> 

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH 2/2] media: v4l2-mem2mem: add a list for buf used by hw
  2023-07-04  4:00 ` [PATCH 2/2] media: v4l2-mem2mem: add a list for buf used by hw Hsia-Jun Li
  2023-07-07 19:20   ` Nicolas Dufresne
  2023-07-11  6:26   ` Dan Carpenter
@ 2023-07-12  9:33   ` Tomasz Figa
  2023-07-17  7:14     ` Hsia-Jun Li
  2023-07-17 14:07     ` Nicolas Dufresne
  2 siblings, 2 replies; 33+ messages in thread
From: Tomasz Figa @ 2023-07-12  9:33 UTC (permalink / raw)
  To: Hsia-Jun Li
  Cc: linux-media, ayaka, hans.verkuil, mchehab, laurent.pinchart,
	hiroh, hverkuil, linux-kernel, nicolas

On Tue, Jul 04, 2023 at 12:00:38PM +0800, Hsia-Jun Li wrote:
> From: "Hsia-Jun(Randy) Li" <randy.li@synaptics.com>
> 
> Many drivers have to create its own buf_struct for a
> vb2_queue to track such a state. Also driver has to
> iterate over rdy_queue every times to find out a buffer
> which is not sent to hardware(or firmware), this new
> list just offers the driver a place to store the buffer
> that hardware(firmware) has acknowledged.
> 
> One important advance about this list, it doesn't like
> rdy_queue which both bottom half of the user calling
> could operate it, while the v4l2 worker would as well.
> The v4l2 core could only operate this queue when its
> v4l2_context is not running, the driver would only
> access this new hw_queue in its own worker.

Could you describe in what case such a list would be useful for a
mem2mem driver?

> 
> Signed-off-by: Hsia-Jun(Randy) Li <randy.li@synaptics.com>
> ---
>  drivers/media/v4l2-core/v4l2-mem2mem.c | 25 +++++++++++++++++--------
>  include/media/v4l2-mem2mem.h           | 10 +++++++++-
>  2 files changed, 26 insertions(+), 9 deletions(-)
> 
> diff --git a/drivers/media/v4l2-core/v4l2-mem2mem.c b/drivers/media/v4l2-core/v4l2-mem2mem.c
> index c771aba42015..b4151147d5bd 100644
> --- a/drivers/media/v4l2-core/v4l2-mem2mem.c
> +++ b/drivers/media/v4l2-core/v4l2-mem2mem.c
> @@ -321,15 +321,21 @@ static void __v4l2_m2m_try_queue(struct v4l2_m2m_dev *m2m_dev,
>  		goto job_unlock;
>  	}
>  
> -	src = v4l2_m2m_next_src_buf(m2m_ctx);
> -	dst = v4l2_m2m_next_dst_buf(m2m_ctx);
> -	if (!src && !m2m_ctx->out_q_ctx.buffered) {
> -		dprintk("No input buffers available\n");
> -		goto job_unlock;
> +	if (list_empty(&m2m_ctx->out_q_ctx.hw_queue)) {
> +		src = v4l2_m2m_next_src_buf(m2m_ctx);
> +
> +		if (!src && !m2m_ctx->out_q_ctx.buffered) {
> +			dprintk("No input buffers available\n");
> +			goto job_unlock;
> +		}
>  	}
> -	if (!dst && !m2m_ctx->cap_q_ctx.buffered) {
> -		dprintk("No output buffers available\n");
> -		goto job_unlock;
> +
> +	if (list_empty(&m2m_ctx->cap_q_ctx.hw_queue)) {
> +		dst = v4l2_m2m_next_dst_buf(m2m_ctx);
> +		if (!dst && !m2m_ctx->cap_q_ctx.buffered) {
> +			dprintk("No output buffers available\n");
> +			goto job_unlock;
> +		}
>  	}

src and dst would be referenced unitialized below if neither of the
above ifs hits...

Best regards,
Tomasz

>  
>  	m2m_ctx->new_frame = true;
> @@ -896,6 +902,7 @@ int v4l2_m2m_streamoff(struct file *file, struct v4l2_m2m_ctx *m2m_ctx,
>  	INIT_LIST_HEAD(&q_ctx->rdy_queue);
>  	q_ctx->num_rdy = 0;
>  	spin_unlock_irqrestore(&q_ctx->rdy_spinlock, flags);
> +	INIT_LIST_HEAD(&q_ctx->hw_queue);
>  
>  	if (m2m_dev->curr_ctx == m2m_ctx) {
>  		m2m_dev->curr_ctx = NULL;
> @@ -1234,6 +1241,8 @@ struct v4l2_m2m_ctx *v4l2_m2m_ctx_init(struct v4l2_m2m_dev *m2m_dev,
>  
>  	INIT_LIST_HEAD(&out_q_ctx->rdy_queue);
>  	INIT_LIST_HEAD(&cap_q_ctx->rdy_queue);
> +	INIT_LIST_HEAD(&out_q_ctx->hw_queue);
> +	INIT_LIST_HEAD(&cap_q_ctx->hw_queue);
>  	spin_lock_init(&out_q_ctx->rdy_spinlock);
>  	spin_lock_init(&cap_q_ctx->rdy_spinlock);
>  
> diff --git a/include/media/v4l2-mem2mem.h b/include/media/v4l2-mem2mem.h
> index d6c8eb2b5201..2342656e582d 100644
> --- a/include/media/v4l2-mem2mem.h
> +++ b/include/media/v4l2-mem2mem.h
> @@ -53,9 +53,16 @@ struct v4l2_m2m_dev;
>   *	processed
>   *
>   * @q:		pointer to struct &vb2_queue
> - * @rdy_queue:	List of V4L2 mem-to-mem queues
> + * @rdy_queue:	List of V4L2 mem-to-mem queues. If v4l2_m2m_buf_queue() is
> + *		called in struct vb2_ops->buf_queue(), the buffer enqueued
> + *		by user would be added to this list.
>   * @rdy_spinlock: spin lock to protect the struct usage
>   * @num_rdy:	number of buffers ready to be processed
> + * @hw_queue:	A list for tracking the buffer is occupied by the hardware
> + * 		(or device's firmware). A buffer could only be in either
> + * 		this list or @rdy_queue.
> + * 		Driver may choose not to use this list while uses its own
> + * 		private data to do this work.
>   * @buffered:	is the queue buffered?
>   *
>   * Queue for buffers ready to be processed as soon as this
> @@ -68,6 +75,7 @@ struct v4l2_m2m_queue_ctx {
>  	struct list_head	rdy_queue;
>  	spinlock_t		rdy_spinlock;
>  	u8			num_rdy;
> +	struct list_head	hw_queue;
>  	bool			buffered;
>  };
>  
> -- 
> 2.17.1
> 

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH 1/2] [RESEND] media: v4l2-mem2mem: allow device run without buf
  2023-07-12  9:31     ` Tomasz Figa
@ 2023-07-12  9:44       ` Sebastian Fricke
  2023-07-13  3:13         ` Tomasz Figa
  2023-07-17 14:00       ` Nicolas Dufresne
  1 sibling, 1 reply; 33+ messages in thread
From: Sebastian Fricke @ 2023-07-12  9:44 UTC (permalink / raw)
  To: Tomasz Figa
  Cc: Nicolas Dufresne, Hsia-Jun Li, linux-media, ayaka, hans.verkuil,
	mchehab, laurent.pinchart, hiroh, hverkuil, linux-kernel

Hey Tomasz,

On 12.07.2023 09:31, Tomasz Figa wrote:
>On Fri, Jul 07, 2023 at 03:14:23PM -0400, Nicolas Dufresne wrote:
>> Hi Randy,
>>
>> Le mardi 04 juillet 2023 à 12:00 +0800, Hsia-Jun Li a écrit :
>> > From: Randy Li <ayaka@soulik.info>
>> >
>> > For the decoder supports Dynamic Resolution Change,
>> > we don't need to allocate any CAPTURE or graphics buffer
>> > for them at inital CAPTURE setup step.
>> >
>> > We need to make the device run or we can't get those
>> > metadata.
>> >
>> > Signed-off-by: Randy Li <ayaka@soulik.info>
>> > ---
>> >  drivers/media/v4l2-core/v4l2-mem2mem.c | 5 +++--
>> >  1 file changed, 3 insertions(+), 2 deletions(-)
>> >
>> > diff --git a/drivers/media/v4l2-core/v4l2-mem2mem.c b/drivers/media/v4l2-core/v4l2-mem2mem.c
>> > index 0cc30397fbad..c771aba42015 100644
>> > --- a/drivers/media/v4l2-core/v4l2-mem2mem.c
>> > +++ b/drivers/media/v4l2-core/v4l2-mem2mem.c
>> > @@ -301,8 +301,9 @@ static void __v4l2_m2m_try_queue(struct v4l2_m2m_dev *m2m_dev,
>> >
>> >  	dprintk("Trying to schedule a job for m2m_ctx: %p\n", m2m_ctx);
>> >
>> > -	if (!m2m_ctx->out_q_ctx.q.streaming
>> > -	    || !m2m_ctx->cap_q_ctx.q.streaming) {
>> > +	if (!(m2m_ctx->out_q_ctx.q.streaming || m2m_ctx->out_q_ctx.buffered)
>> > +	    || !(m2m_ctx->cap_q_ctx.q.streaming
>> > +		 || m2m_ctx->cap_q_ctx.buffered)) {
>>
>> I have a two atches with similar goals in my wave5 tree. It will be easier to
>> upstream with an actual user, though, I'm probably a month or two away from
>> submitting this driver again.
>>
>> https://gitlab.collabora.com/chipsnmedia/kernel/-/commit/ac59eafd5076c4deb3bfe1fb85b3b776586ef3eb
>> https://gitlab.collabora.com/chipsnmedia/kernel/-/commit/5de4fbe0abb20b8e8d862b654f93e3efeb1ef251
>>
>
>While I'm not going to NAK this series or those 2 patches if you send
>them, I'm not really convinced that adding more and more complexity to
>the mem2mem helpers is a good idea, especially since all of those seem
>to be only needed by stateful video decoders.
>
>The mem2mem framework started as a set of helpers to eliminate boiler
>plate from simple drivers that always get 1 CAPTURE and 1 OUTPUT buffer,
>run 1 processing job on them and then return both of the to the userspace
>and I think it should stay like this.
>
>I think we're strongly in need of a stateful video decoder framework that
>would actually address the exact problems that those have rather than
>bending something that wasn't designed with them in mind to work around the
>differences.

Thanks for the feedback.

I have recently discussed how we could approach creating a framework for
the codecs side, with Hans Verkuil and Nicolas Dufresne.

The first step we would have to do is come up with a list of
requirements for that framework and expected future needs, maybe we can
start a public discussion on the mailing list to generate a list like
that.
But all in all this endeavor will probably require quite a bit of time
and effort, do you think we could modify M2M a bit for our use case and
then when we are in the process of creating the new framework, we could
maybe think about simplifying the M2M framework again?

>
>Best regards,
>Tomasz

Greetings,
Sebastian

>
>> Sebastien and I authored this without giving it much thought, but we believe
>> this massively simplify our handling of DRC (dynamic resolution change).
>>
>> The main difference, is that we added ignore_streaming to the ctx, so that
>> drivers can opt-in the mode of operation. Thinking it would avoid any potential
>> side effects in drivers that aren't prepared to that. We didn't want to tied it
>> up to buffered, this is open to discussion of course, we do use buffered on both
>> queues and use a slightly more advance job_ready function, that take into
>> account our driver state.
>>
>> In short, Sebastien and I agree this small change is the right direction, we
>> simply have a different implementation. I can send it as RFC if one believe its
>> would be useful now (even without a user).
>>
>> >  		dprintk("Streaming needs to be on for both queues\n");
>> >  		return;
>> >  	}
>>

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH 1/2] [RESEND] media: v4l2-mem2mem: allow device run without buf
  2023-07-12  9:44       ` Sebastian Fricke
@ 2023-07-13  3:13         ` Tomasz Figa
  0 siblings, 0 replies; 33+ messages in thread
From: Tomasz Figa @ 2023-07-13  3:13 UTC (permalink / raw)
  To: Sebastian Fricke
  Cc: Nicolas Dufresne, Hsia-Jun Li, linux-media, ayaka, hans.verkuil,
	mchehab, laurent.pinchart, hiroh, hverkuil, linux-kernel, mcasas,
	Steve Cho, Fritz Koenig, wenst, nhebert

On Wed, Jul 12, 2023 at 6:44 PM Sebastian Fricke
<sebastian.fricke@collabora.com> wrote:
>
> Hey Tomasz,
>
> On 12.07.2023 09:31, Tomasz Figa wrote:
> >On Fri, Jul 07, 2023 at 03:14:23PM -0400, Nicolas Dufresne wrote:
> >> Hi Randy,
> >>
> >> Le mardi 04 juillet 2023 à 12:00 +0800, Hsia-Jun Li a écrit :
> >> > From: Randy Li <ayaka@soulik.info>
> >> >
> >> > For the decoder supports Dynamic Resolution Change,
> >> > we don't need to allocate any CAPTURE or graphics buffer
> >> > for them at inital CAPTURE setup step.
> >> >
> >> > We need to make the device run or we can't get those
> >> > metadata.
> >> >
> >> > Signed-off-by: Randy Li <ayaka@soulik.info>
> >> > ---
> >> >  drivers/media/v4l2-core/v4l2-mem2mem.c | 5 +++--
> >> >  1 file changed, 3 insertions(+), 2 deletions(-)
> >> >
> >> > diff --git a/drivers/media/v4l2-core/v4l2-mem2mem.c b/drivers/media/v4l2-core/v4l2-mem2mem.c
> >> > index 0cc30397fbad..c771aba42015 100644
> >> > --- a/drivers/media/v4l2-core/v4l2-mem2mem.c
> >> > +++ b/drivers/media/v4l2-core/v4l2-mem2mem.c
> >> > @@ -301,8 +301,9 @@ static void __v4l2_m2m_try_queue(struct v4l2_m2m_dev *m2m_dev,
> >> >
> >> >    dprintk("Trying to schedule a job for m2m_ctx: %p\n", m2m_ctx);
> >> >
> >> > -  if (!m2m_ctx->out_q_ctx.q.streaming
> >> > -      || !m2m_ctx->cap_q_ctx.q.streaming) {
> >> > +  if (!(m2m_ctx->out_q_ctx.q.streaming || m2m_ctx->out_q_ctx.buffered)
> >> > +      || !(m2m_ctx->cap_q_ctx.q.streaming
> >> > +           || m2m_ctx->cap_q_ctx.buffered)) {
> >>
> >> I have a two atches with similar goals in my wave5 tree. It will be easier to
> >> upstream with an actual user, though, I'm probably a month or two away from
> >> submitting this driver again.
> >>
> >> https://gitlab.collabora.com/chipsnmedia/kernel/-/commit/ac59eafd5076c4deb3bfe1fb85b3b776586ef3eb
> >> https://gitlab.collabora.com/chipsnmedia/kernel/-/commit/5de4fbe0abb20b8e8d862b654f93e3efeb1ef251
> >>
> >
> >While I'm not going to NAK this series or those 2 patches if you send
> >them, I'm not really convinced that adding more and more complexity to
> >the mem2mem helpers is a good idea, especially since all of those seem
> >to be only needed by stateful video decoders.
> >
> >The mem2mem framework started as a set of helpers to eliminate boiler
> >plate from simple drivers that always get 1 CAPTURE and 1 OUTPUT buffer,
> >run 1 processing job on them and then return both of the to the userspace
> >and I think it should stay like this.
> >
> >I think we're strongly in need of a stateful video decoder framework that
> >would actually address the exact problems that those have rather than
> >bending something that wasn't designed with them in mind to work around the
> >differences.
>
> Thanks for the feedback.
>
> I have recently discussed how we could approach creating a framework for
> the codecs side, with Hans Verkuil and Nicolas Dufresne.

That's great to hear, thanks. :)

>
> The first step we would have to do is come up with a list of
> requirements for that framework and expected future needs, maybe we can
> start a public discussion on the mailing list to generate a list like
> that.

Makes sense. Let me CC some ChromeOS folks working on video codec
drivers these days.

> But all in all this endeavor will probably require quite a bit of time
> and effort, do you think we could modify M2M a bit for our use case and
> then when we are in the process of creating the new framework, we could
> maybe think about simplifying the M2M framework again?

Sure, as I said, I'm not NAKing this series.

>
> >
> >Best regards,
> >Tomasz
>
> Greetings,
> Sebastian
>
> >
> >> Sebastien and I authored this without giving it much thought, but we believe
> >> this massively simplify our handling of DRC (dynamic resolution change).
> >>
> >> The main difference, is that we added ignore_streaming to the ctx, so that
> >> drivers can opt-in the mode of operation. Thinking it would avoid any potential
> >> side effects in drivers that aren't prepared to that. We didn't want to tied it
> >> up to buffered, this is open to discussion of course, we do use buffered on both
> >> queues and use a slightly more advance job_ready function, that take into
> >> account our driver state.
> >>
> >> In short, Sebastien and I agree this small change is the right direction, we
> >> simply have a different implementation. I can send it as RFC if one believe its
> >> would be useful now (even without a user).
> >>
> >> >            dprintk("Streaming needs to be on for both queues\n");
> >> >            return;
> >> >    }
> >>

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH 2/2] media: v4l2-mem2mem: add a list for buf used by hw
  2023-07-12  9:33   ` Tomasz Figa
@ 2023-07-17  7:14     ` Hsia-Jun Li
  2023-07-27  7:25       ` Tomasz Figa
  2023-07-17 14:07     ` Nicolas Dufresne
  1 sibling, 1 reply; 33+ messages in thread
From: Hsia-Jun Li @ 2023-07-17  7:14 UTC (permalink / raw)
  To: Tomasz Figa
  Cc: linux-media, ayaka, hans.verkuil, mchehab, laurent.pinchart,
	hiroh, hverkuil, linux-kernel, nicolas


On 7/12/23 17:33, Tomasz Figa wrote:
> CAUTION: Email originated externally, do not click links or open attachments unless you recognize the sender and know the content is safe.
>
>
> On Tue, Jul 04, 2023 at 12:00:38PM +0800, Hsia-Jun Li wrote:
>> From: "Hsia-Jun(Randy) Li" <randy.li@synaptics.com>
>>
>> Many drivers have to create its own buf_struct for a
>> vb2_queue to track such a state. Also driver has to
>> iterate over rdy_queue every times to find out a buffer
>> which is not sent to hardware(or firmware), this new
>> list just offers the driver a place to store the buffer
>> that hardware(firmware) has acknowledged.
>>
>> One important advance about this list, it doesn't like
>> rdy_queue which both bottom half of the user calling
>> could operate it, while the v4l2 worker would as well.
>> The v4l2 core could only operate this queue when its
>> v4l2_context is not running, the driver would only
>> access this new hw_queue in its own worker.
> Could you describe in what case such a list would be useful for a
> mem2mem driver?

This list, as its description, just for saving us from creating a 
private buffer struct to track buffer state.

The queue in the kernel is not the queue that hardware(codec firmware) 
are using.


>> Signed-off-by: Hsia-Jun(Randy) Li <randy.li@synaptics.com>
>> ---
>>   drivers/media/v4l2-core/v4l2-mem2mem.c | 25 +++++++++++++++++--------
>>   include/media/v4l2-mem2mem.h           | 10 +++++++++-
>>   2 files changed, 26 insertions(+), 9 deletions(-)
>>
>> diff --git a/drivers/media/v4l2-core/v4l2-mem2mem.c b/drivers/media/v4l2-core/v4l2-mem2mem.c
>> index c771aba42015..b4151147d5bd 100644
>> --- a/drivers/media/v4l2-core/v4l2-mem2mem.c
>> +++ b/drivers/media/v4l2-core/v4l2-mem2mem.c
>> @@ -321,15 +321,21 @@ static void __v4l2_m2m_try_queue(struct v4l2_m2m_dev *m2m_dev,
>>                goto job_unlock;
>>        }
>>
>> -     src = v4l2_m2m_next_src_buf(m2m_ctx);
>> -     dst = v4l2_m2m_next_dst_buf(m2m_ctx);
>> -     if (!src && !m2m_ctx->out_q_ctx.buffered) {
>> -             dprintk("No input buffers available\n");
>> -             goto job_unlock;
>> +     if (list_empty(&m2m_ctx->out_q_ctx.hw_queue)) {
>> +             src = v4l2_m2m_next_src_buf(m2m_ctx);
>> +
>> +             if (!src && !m2m_ctx->out_q_ctx.buffered) {
>> +                     dprintk("No input buffers available\n");
>> +                     goto job_unlock;
>> +             }
>>        }
>> -     if (!dst && !m2m_ctx->cap_q_ctx.buffered) {
>> -             dprintk("No output buffers available\n");
>> -             goto job_unlock;
>> +
>> +     if (list_empty(&m2m_ctx->cap_q_ctx.hw_queue)) {
>> +             dst = v4l2_m2m_next_dst_buf(m2m_ctx);
>> +             if (!dst && !m2m_ctx->cap_q_ctx.buffered) {
>> +                     dprintk("No output buffers available\n");
>> +                     goto job_unlock;
>> +             }
>>        }
> src and dst would be referenced unitialized below if neither of the
> above ifs hits...
I think they have been initialized at v4l2_m2m_ctx_init()
>
> Best regards,
> Tomasz
>
>>        m2m_ctx->new_frame = true;
>> @@ -896,6 +902,7 @@ int v4l2_m2m_streamoff(struct file *file, struct v4l2_m2m_ctx *m2m_ctx,
>>        INIT_LIST_HEAD(&q_ctx->rdy_queue);
>>        q_ctx->num_rdy = 0;
>>        spin_unlock_irqrestore(&q_ctx->rdy_spinlock, flags);
>> +     INIT_LIST_HEAD(&q_ctx->hw_queue);
>>
>>        if (m2m_dev->curr_ctx == m2m_ctx) {
>>                m2m_dev->curr_ctx = NULL;
>> @@ -1234,6 +1241,8 @@ struct v4l2_m2m_ctx *v4l2_m2m_ctx_init(struct v4l2_m2m_dev *m2m_dev,
>>
>>        INIT_LIST_HEAD(&out_q_ctx->rdy_queue);
>>        INIT_LIST_HEAD(&cap_q_ctx->rdy_queue);
>> +     INIT_LIST_HEAD(&out_q_ctx->hw_queue);
>> +     INIT_LIST_HEAD(&cap_q_ctx->hw_queue);
>>        spin_lock_init(&out_q_ctx->rdy_spinlock);
>>        spin_lock_init(&cap_q_ctx->rdy_spinlock);
>>
>> diff --git a/include/media/v4l2-mem2mem.h b/include/media/v4l2-mem2mem.h
>> index d6c8eb2b5201..2342656e582d 100644
>> --- a/include/media/v4l2-mem2mem.h
>> +++ b/include/media/v4l2-mem2mem.h
>> @@ -53,9 +53,16 @@ struct v4l2_m2m_dev;
>>    *   processed
>>    *
>>    * @q:               pointer to struct &vb2_queue
>> - * @rdy_queue:       List of V4L2 mem-to-mem queues
>> + * @rdy_queue:       List of V4L2 mem-to-mem queues. If v4l2_m2m_buf_queue() is
>> + *           called in struct vb2_ops->buf_queue(), the buffer enqueued
>> + *           by user would be added to this list.
>>    * @rdy_spinlock: spin lock to protect the struct usage
>>    * @num_rdy: number of buffers ready to be processed
>> + * @hw_queue:        A list for tracking the buffer is occupied by the hardware
>> + *           (or device's firmware). A buffer could only be in either
>> + *           this list or @rdy_queue.
>> + *           Driver may choose not to use this list while uses its own
>> + *           private data to do this work.
>>    * @buffered:        is the queue buffered?
>>    *
>>    * Queue for buffers ready to be processed as soon as this
>> @@ -68,6 +75,7 @@ struct v4l2_m2m_queue_ctx {
>>        struct list_head        rdy_queue;
>>        spinlock_t              rdy_spinlock;
>>        u8                      num_rdy;
>> +     struct list_head        hw_queue;
>>        bool                    buffered;
>>   };
>>
>> --
>> 2.17.1
>>
-- 
Hsia-Jun(Randy) Li


^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH 1/2] [RESEND] media: v4l2-mem2mem: allow device run without buf
  2023-07-12  9:31     ` Tomasz Figa
  2023-07-12  9:44       ` Sebastian Fricke
@ 2023-07-17 14:00       ` Nicolas Dufresne
  2023-07-21  8:56         ` Hsia-Jun Li
  1 sibling, 1 reply; 33+ messages in thread
From: Nicolas Dufresne @ 2023-07-17 14:00 UTC (permalink / raw)
  To: Tomasz Figa
  Cc: Hsia-Jun Li, linux-media, ayaka, hans.verkuil, mchehab,
	laurent.pinchart, hiroh, hverkuil, linux-kernel,
	Sebastian Fricke

Le mercredi 12 juillet 2023 à 09:31 +0000, Tomasz Figa a écrit :
> On Fri, Jul 07, 2023 at 03:14:23PM -0400, Nicolas Dufresne wrote:
> > Hi Randy,
> > 
> > Le mardi 04 juillet 2023 à 12:00 +0800, Hsia-Jun Li a écrit :
> > > From: Randy Li <ayaka@soulik.info>
> > > 
> > > For the decoder supports Dynamic Resolution Change,
> > > we don't need to allocate any CAPTURE or graphics buffer
> > > for them at inital CAPTURE setup step.
> > > 
> > > We need to make the device run or we can't get those
> > > metadata.
> > > 
> > > Signed-off-by: Randy Li <ayaka@soulik.info>
> > > ---
> > >  drivers/media/v4l2-core/v4l2-mem2mem.c | 5 +++--
> > >  1 file changed, 3 insertions(+), 2 deletions(-)
> > > 
> > > diff --git a/drivers/media/v4l2-core/v4l2-mem2mem.c b/drivers/media/v4l2-core/v4l2-mem2mem.c
> > > index 0cc30397fbad..c771aba42015 100644
> > > --- a/drivers/media/v4l2-core/v4l2-mem2mem.c
> > > +++ b/drivers/media/v4l2-core/v4l2-mem2mem.c
> > > @@ -301,8 +301,9 @@ static void __v4l2_m2m_try_queue(struct v4l2_m2m_dev *m2m_dev,
> > >  
> > >  	dprintk("Trying to schedule a job for m2m_ctx: %p\n", m2m_ctx);
> > >  
> > > -	if (!m2m_ctx->out_q_ctx.q.streaming
> > > -	    || !m2m_ctx->cap_q_ctx.q.streaming) {
> > > +	if (!(m2m_ctx->out_q_ctx.q.streaming || m2m_ctx->out_q_ctx.buffered)
> > > +	    || !(m2m_ctx->cap_q_ctx.q.streaming
> > > +		 || m2m_ctx->cap_q_ctx.buffered)) {
> > 
> > I have a two atches with similar goals in my wave5 tree. It will be easier to
> > upstream with an actual user, though, I'm probably a month or two away from
> > submitting this driver again.
> > 
> > https://gitlab.collabora.com/chipsnmedia/kernel/-/commit/ac59eafd5076c4deb3bfe1fb85b3b776586ef3eb
> > https://gitlab.collabora.com/chipsnmedia/kernel/-/commit/5de4fbe0abb20b8e8d862b654f93e3efeb1ef251
> > 
> 
> While I'm not going to NAK this series or those 2 patches if you send
> them, I'm not really convinced that adding more and more complexity to
> the mem2mem helpers is a good idea, especially since all of those seem
> to be only needed by stateful video decoders.
> 
> The mem2mem framework started as a set of helpers to eliminate boiler
> plate from simple drivers that always get 1 CAPTURE and 1 OUTPUT buffer,
> run 1 processing job on them and then return both of the to the userspace
> and I think it should stay like this.

Its a bit late to try and bring that argument. It should have been raised couple
of years ago (before I even started helping with these CODEC). Now that all the
newly written stately decoders uses this framework, it is logical to keep
reducing the boiler plate for these too. In my opinion, the job_ready()
callback, should have been a lot more flexible from the start. And allowing
driver to make it more powerful does not really add that much complexity.

Speaking of complexity, driving the output manually (outside of the job
workqueue) during sequence initialization is a way more complex and risky then
this. Finally, sticking with 1:1 pattern means encoder, detilers, image
enhancement reducing framerate, etc. would all be unwelcome to use this. Which
in short, means no one should even use this.

> 
> I think we're strongly in need of a stateful video decoder framework that
> would actually address the exact problems that those have rather than
> bending something that wasn't designed with them in mind to work around the
> differences.

The bend is already there, of course I'd be happy to help with any new
framework. Specially on modern stateless, were there is a need to do better
scheduling. Just ping me if you have some effort starting, I don't currently
have a budget or bandwidth to write new drivers or port existing drivers them on
a newly written framework.

Nicolas


[...]

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH 2/2] media: v4l2-mem2mem: add a list for buf used by hw
  2023-07-12  9:33   ` Tomasz Figa
  2023-07-17  7:14     ` Hsia-Jun Li
@ 2023-07-17 14:07     ` Nicolas Dufresne
  2023-07-18  3:53       ` Hsia-Jun Li
  2023-07-27  7:43       ` Tomasz Figa
  1 sibling, 2 replies; 33+ messages in thread
From: Nicolas Dufresne @ 2023-07-17 14:07 UTC (permalink / raw)
  To: Tomasz Figa, Hsia-Jun Li
  Cc: linux-media, ayaka, hans.verkuil, mchehab, laurent.pinchart,
	hiroh, hverkuil, linux-kernel

Le mercredi 12 juillet 2023 à 09:33 +0000, Tomasz Figa a écrit :
> On Tue, Jul 04, 2023 at 12:00:38PM +0800, Hsia-Jun Li wrote:
> > From: "Hsia-Jun(Randy) Li" <randy.li@synaptics.com>
> > 
> > Many drivers have to create its own buf_struct for a
> > vb2_queue to track such a state. Also driver has to
> > iterate over rdy_queue every times to find out a buffer
> > which is not sent to hardware(or firmware), this new
> > list just offers the driver a place to store the buffer
> > that hardware(firmware) has acknowledged.
> > 
> > One important advance about this list, it doesn't like
> > rdy_queue which both bottom half of the user calling
> > could operate it, while the v4l2 worker would as well.
> > The v4l2 core could only operate this queue when its
> > v4l2_context is not running, the driver would only
> > access this new hw_queue in its own worker.
> 
> Could you describe in what case such a list would be useful for a
> mem2mem driver?

Today all driver must track buffers that are "owned by the hardware". This is a
concept dictated by the m2m framework and enforced through the ACTIVE flag. All
buffers from this list must be mark as done/error/queued after streamoff of the
respective queue in order to acknowledge that they are no longer in use by the
HW. Not doing so will warn:

  videobuf2_common: driver bug: stop_streaming operation is leaving buf ...

Though, there is no queue to easily iterate them. All driver endup having their
own queue, or just leaving the buffers in the rdy_queue (which isn't better).

Nicolas
> 
> > 
> > Signed-off-by: Hsia-Jun(Randy) Li <randy.li@synaptics.com>
> > ---
> >  drivers/media/v4l2-core/v4l2-mem2mem.c | 25 +++++++++++++++++--------
> >  include/media/v4l2-mem2mem.h           | 10 +++++++++-
> >  2 files changed, 26 insertions(+), 9 deletions(-)
> > 
> > diff --git a/drivers/media/v4l2-core/v4l2-mem2mem.c b/drivers/media/v4l2-core/v4l2-mem2mem.c
> > index c771aba42015..b4151147d5bd 100644
> > --- a/drivers/media/v4l2-core/v4l2-mem2mem.c
> > +++ b/drivers/media/v4l2-core/v4l2-mem2mem.c
> > @@ -321,15 +321,21 @@ static void __v4l2_m2m_try_queue(struct v4l2_m2m_dev *m2m_dev,
> >  		goto job_unlock;
> >  	}
> >  
> > -	src = v4l2_m2m_next_src_buf(m2m_ctx);
> > -	dst = v4l2_m2m_next_dst_buf(m2m_ctx);
> > -	if (!src && !m2m_ctx->out_q_ctx.buffered) {
> > -		dprintk("No input buffers available\n");
> > -		goto job_unlock;
> > +	if (list_empty(&m2m_ctx->out_q_ctx.hw_queue)) {
> > +		src = v4l2_m2m_next_src_buf(m2m_ctx);
> > +
> > +		if (!src && !m2m_ctx->out_q_ctx.buffered) {
> > +			dprintk("No input buffers available\n");
> > +			goto job_unlock;
> > +		}
> >  	}
> > -	if (!dst && !m2m_ctx->cap_q_ctx.buffered) {
> > -		dprintk("No output buffers available\n");
> > -		goto job_unlock;
> > +
> > +	if (list_empty(&m2m_ctx->cap_q_ctx.hw_queue)) {
> > +		dst = v4l2_m2m_next_dst_buf(m2m_ctx);
> > +		if (!dst && !m2m_ctx->cap_q_ctx.buffered) {
> > +			dprintk("No output buffers available\n");
> > +			goto job_unlock;
> > +		}
> >  	}
> 
> src and dst would be referenced unitialized below if neither of the
> above ifs hits...
> 
> Best regards,
> Tomasz
> 
> >  
> >  	m2m_ctx->new_frame = true;
> > @@ -896,6 +902,7 @@ int v4l2_m2m_streamoff(struct file *file, struct v4l2_m2m_ctx *m2m_ctx,
> >  	INIT_LIST_HEAD(&q_ctx->rdy_queue);
> >  	q_ctx->num_rdy = 0;
> >  	spin_unlock_irqrestore(&q_ctx->rdy_spinlock, flags);
> > +	INIT_LIST_HEAD(&q_ctx->hw_queue);
> >  
> >  	if (m2m_dev->curr_ctx == m2m_ctx) {
> >  		m2m_dev->curr_ctx = NULL;
> > @@ -1234,6 +1241,8 @@ struct v4l2_m2m_ctx *v4l2_m2m_ctx_init(struct v4l2_m2m_dev *m2m_dev,
> >  
> >  	INIT_LIST_HEAD(&out_q_ctx->rdy_queue);
> >  	INIT_LIST_HEAD(&cap_q_ctx->rdy_queue);
> > +	INIT_LIST_HEAD(&out_q_ctx->hw_queue);
> > +	INIT_LIST_HEAD(&cap_q_ctx->hw_queue);
> >  	spin_lock_init(&out_q_ctx->rdy_spinlock);
> >  	spin_lock_init(&cap_q_ctx->rdy_spinlock);
> >  
> > diff --git a/include/media/v4l2-mem2mem.h b/include/media/v4l2-mem2mem.h
> > index d6c8eb2b5201..2342656e582d 100644
> > --- a/include/media/v4l2-mem2mem.h
> > +++ b/include/media/v4l2-mem2mem.h
> > @@ -53,9 +53,16 @@ struct v4l2_m2m_dev;
> >   *	processed
> >   *
> >   * @q:		pointer to struct &vb2_queue
> > - * @rdy_queue:	List of V4L2 mem-to-mem queues
> > + * @rdy_queue:	List of V4L2 mem-to-mem queues. If v4l2_m2m_buf_queue() is
> > + *		called in struct vb2_ops->buf_queue(), the buffer enqueued
> > + *		by user would be added to this list.
> >   * @rdy_spinlock: spin lock to protect the struct usage
> >   * @num_rdy:	number of buffers ready to be processed
> > + * @hw_queue:	A list for tracking the buffer is occupied by the hardware
> > + * 		(or device's firmware). A buffer could only be in either
> > + * 		this list or @rdy_queue.
> > + * 		Driver may choose not to use this list while uses its own
> > + * 		private data to do this work.
> >   * @buffered:	is the queue buffered?
> >   *
> >   * Queue for buffers ready to be processed as soon as this
> > @@ -68,6 +75,7 @@ struct v4l2_m2m_queue_ctx {
> >  	struct list_head	rdy_queue;
> >  	spinlock_t		rdy_spinlock;
> >  	u8			num_rdy;
> > +	struct list_head	hw_queue;
> >  	bool			buffered;
> >  };
> >  
> > -- 
> > 2.17.1
> > 


^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH 2/2] media: v4l2-mem2mem: add a list for buf used by hw
  2023-07-17 14:07     ` Nicolas Dufresne
@ 2023-07-18  3:53       ` Hsia-Jun Li
  2023-07-27  7:43       ` Tomasz Figa
  1 sibling, 0 replies; 33+ messages in thread
From: Hsia-Jun Li @ 2023-07-18  3:53 UTC (permalink / raw)
  To: Nicolas Dufresne
  Cc: linux-media, Tomasz Figa, ayaka, hans.verkuil, mchehab,
	laurent.pinchart, hiroh, hverkuil, linux-kernel


On 7/17/23 22:07, Nicolas Dufresne wrote:
> CAUTION: Email originated externally, do not click links or open attachments unless you recognize the sender and know the content is safe.
>
>
> Le mercredi 12 juillet 2023 à 09:33 +0000, Tomasz Figa a écrit :
>> On Tue, Jul 04, 2023 at 12:00:38PM +0800, Hsia-Jun Li wrote:
>>> From: "Hsia-Jun(Randy) Li" <randy.li@synaptics.com>
>>>
>>> Many drivers have to create its own buf_struct for a
>>> vb2_queue to track such a state. Also driver has to
>>> iterate over rdy_queue every times to find out a buffer
>>> which is not sent to hardware(or firmware), this new
>>> list just offers the driver a place to store the buffer
>>> that hardware(firmware) has acknowledged.
>>>
>>> One important advance about this list, it doesn't like
>>> rdy_queue which both bottom half of the user calling
>>> could operate it, while the v4l2 worker would as well.
>>> The v4l2 core could only operate this queue when its
>>> v4l2_context is not running, the driver would only
>>> access this new hw_queue in its own worker.
>> Could you describe in what case such a list would be useful for a
>> mem2mem driver?
> Today all driver must track buffers that are "owned by the hardware". This is a
> concept dictated by the m2m framework and enforced through the ACTIVE flag.

I think that flag is confusing, the m2m framework would only set this 
flag when a buffer is enqueue into v4l2 (__enqueue_in_driver()).

The application can't know whether the driver(or hardware) would still 
use it when that buffer is dequeued(__vb2_dqbuf() would override the 
state here).

I was trying to suggest a flag for the new DELETE_BUF ioctl() or it 
could delete a buffer which the hardware could still use in the future, 
if we are not in the case for non-secure stateless codec.

> All
> buffers from this list must be mark as done/error/queued after streamoff of the
> respective queue in order to acknowledge that they are no longer in use by the
> HW. Not doing so will warn:
>
>    videobuf2_common: driver bug: stop_streaming operation is leaving buf ...
>
> Though, there is no queue to easily iterate them. All driver endup having their
> own queue, or just leaving the buffers in the rdy_queue (which isn't better).
>
> Nicolas
>>> Signed-off-by: Hsia-Jun(Randy) Li <randy.li@synaptics.com>
>>> ---
>>>   drivers/media/v4l2-core/v4l2-mem2mem.c | 25 +++++++++++++++++--------
>>>   include/media/v4l2-mem2mem.h           | 10 +++++++++-
>>>   2 files changed, 26 insertions(+), 9 deletions(-)
>>>
>>> diff --git a/drivers/media/v4l2-core/v4l2-mem2mem.c b/drivers/media/v4l2-core/v4l2-mem2mem.c
>>> index c771aba42015..b4151147d5bd 100644
>>> --- a/drivers/media/v4l2-core/v4l2-mem2mem.c
>>> +++ b/drivers/media/v4l2-core/v4l2-mem2mem.c
>>> @@ -321,15 +321,21 @@ static void __v4l2_m2m_try_queue(struct v4l2_m2m_dev *m2m_dev,
>>>              goto job_unlock;
>>>      }
>>>
>>> -   src = v4l2_m2m_next_src_buf(m2m_ctx);
>>> -   dst = v4l2_m2m_next_dst_buf(m2m_ctx);
>>> -   if (!src && !m2m_ctx->out_q_ctx.buffered) {
>>> -           dprintk("No input buffers available\n");
>>> -           goto job_unlock;
>>> +   if (list_empty(&m2m_ctx->out_q_ctx.hw_queue)) {
>>> +           src = v4l2_m2m_next_src_buf(m2m_ctx);
>>> +
>>> +           if (!src && !m2m_ctx->out_q_ctx.buffered) {
>>> +                   dprintk("No input buffers available\n");
>>> +                   goto job_unlock;
>>> +           }
>>>      }
>>> -   if (!dst && !m2m_ctx->cap_q_ctx.buffered) {
>>> -           dprintk("No output buffers available\n");
>>> -           goto job_unlock;
>>> +
>>> +   if (list_empty(&m2m_ctx->cap_q_ctx.hw_queue)) {
>>> +           dst = v4l2_m2m_next_dst_buf(m2m_ctx);
>>> +           if (!dst && !m2m_ctx->cap_q_ctx.buffered) {
>>> +                   dprintk("No output buffers available\n");
>>> +                   goto job_unlock;
>>> +           }
>>>      }
>> src and dst would be referenced unitialized below if neither of the
>> above ifs hits...
>>
>> Best regards,
>> Tomasz
>>
>>>      m2m_ctx->new_frame = true;
>>> @@ -896,6 +902,7 @@ int v4l2_m2m_streamoff(struct file *file, struct v4l2_m2m_ctx *m2m_ctx,
>>>      INIT_LIST_HEAD(&q_ctx->rdy_queue);
>>>      q_ctx->num_rdy = 0;
>>>      spin_unlock_irqrestore(&q_ctx->rdy_spinlock, flags);
>>> +   INIT_LIST_HEAD(&q_ctx->hw_queue);
>>>
>>>      if (m2m_dev->curr_ctx == m2m_ctx) {
>>>              m2m_dev->curr_ctx = NULL;
>>> @@ -1234,6 +1241,8 @@ struct v4l2_m2m_ctx *v4l2_m2m_ctx_init(struct v4l2_m2m_dev *m2m_dev,
>>>
>>>      INIT_LIST_HEAD(&out_q_ctx->rdy_queue);
>>>      INIT_LIST_HEAD(&cap_q_ctx->rdy_queue);
>>> +   INIT_LIST_HEAD(&out_q_ctx->hw_queue);
>>> +   INIT_LIST_HEAD(&cap_q_ctx->hw_queue);
>>>      spin_lock_init(&out_q_ctx->rdy_spinlock);
>>>      spin_lock_init(&cap_q_ctx->rdy_spinlock);
>>>
>>> diff --git a/include/media/v4l2-mem2mem.h b/include/media/v4l2-mem2mem.h
>>> index d6c8eb2b5201..2342656e582d 100644
>>> --- a/include/media/v4l2-mem2mem.h
>>> +++ b/include/media/v4l2-mem2mem.h
>>> @@ -53,9 +53,16 @@ struct v4l2_m2m_dev;
>>>    * processed
>>>    *
>>>    * @q:             pointer to struct &vb2_queue
>>> - * @rdy_queue:     List of V4L2 mem-to-mem queues
>>> + * @rdy_queue:     List of V4L2 mem-to-mem queues. If v4l2_m2m_buf_queue() is
>>> + *         called in struct vb2_ops->buf_queue(), the buffer enqueued
>>> + *         by user would be added to this list.
>>>    * @rdy_spinlock: spin lock to protect the struct usage
>>>    * @num_rdy:       number of buffers ready to be processed
>>> + * @hw_queue:      A list for tracking the buffer is occupied by the hardware
>>> + *                 (or device's firmware). A buffer could only be in either
>>> + *                 this list or @rdy_queue.
>>> + *                 Driver may choose not to use this list while uses its own
>>> + *                 private data to do this work.
>>>    * @buffered:      is the queue buffered?
>>>    *
>>>    * Queue for buffers ready to be processed as soon as this
>>> @@ -68,6 +75,7 @@ struct v4l2_m2m_queue_ctx {
>>>      struct list_head        rdy_queue;
>>>      spinlock_t              rdy_spinlock;
>>>      u8                      num_rdy;
>>> +   struct list_head        hw_queue;
>>>      bool                    buffered;
>>>   };
>>>
>>> --
>>> 2.17.1
>>>
-- 
Hsia-Jun(Randy) Li


^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH 1/2] [RESEND] media: v4l2-mem2mem: allow device run without buf
  2023-07-17 14:00       ` Nicolas Dufresne
@ 2023-07-21  8:56         ` Hsia-Jun Li
  2023-07-21 16:22           ` Nicolas Dufresne
  0 siblings, 1 reply; 33+ messages in thread
From: Hsia-Jun Li @ 2023-07-21  8:56 UTC (permalink / raw)
  To: Tomasz Figa, Nicolas Dufresne
  Cc: linux-media, ayaka, hans.verkuil, mchehab, laurent.pinchart,
	hiroh, hverkuil, linux-kernel, Sebastian Fricke



On 7/17/23 22:00, Nicolas Dufresne wrote:
> CAUTION: Email originated externally, do not click links or open attachments unless you recognize the sender and know the content is safe.
> 
> 
> Le mercredi 12 juillet 2023 à 09:31 +0000, Tomasz Figa a écrit :
>> On Fri, Jul 07, 2023 at 03:14:23PM -0400, Nicolas Dufresne wrote:
>>> Hi Randy,
>>>
>>> Le mardi 04 juillet 2023 à 12:00 +0800, Hsia-Jun Li a écrit :
>>>> From: Randy Li <ayaka@soulik.info>
>>>>
>>>> For the decoder supports Dynamic Resolution Change,
>>>> we don't need to allocate any CAPTURE or graphics buffer
>>>> for them at inital CAPTURE setup step.
>>>>
>>>> We need to make the device run or we can't get those
>>>> metadata.
>>>>
>>>> Signed-off-by: Randy Li <ayaka@soulik.info>
>>>> ---
>>>>   drivers/media/v4l2-core/v4l2-mem2mem.c | 5 +++--
>>>>   1 file changed, 3 insertions(+), 2 deletions(-)
>>>>
>>>> diff --git a/drivers/media/v4l2-core/v4l2-mem2mem.c b/drivers/media/v4l2-core/v4l2-mem2mem.c
>>>> index 0cc30397fbad..c771aba42015 100644
>>>> --- a/drivers/media/v4l2-core/v4l2-mem2mem.c
>>>> +++ b/drivers/media/v4l2-core/v4l2-mem2mem.c
>>>> @@ -301,8 +301,9 @@ static void __v4l2_m2m_try_queue(struct v4l2_m2m_dev *m2m_dev,
>>>>
>>>>    dprintk("Trying to schedule a job for m2m_ctx: %p\n", m2m_ctx);
>>>>
>>>> - if (!m2m_ctx->out_q_ctx.q.streaming
>>>> -     || !m2m_ctx->cap_q_ctx.q.streaming) {
>>>> + if (!(m2m_ctx->out_q_ctx.q.streaming || m2m_ctx->out_q_ctx.buffered)
>>>> +     || !(m2m_ctx->cap_q_ctx.q.streaming
>>>> +          || m2m_ctx->cap_q_ctx.buffered)) {
>>>
>>> I have a two atches with similar goals in my wave5 tree. It will be easier to
>>> upstream with an actual user, though, I'm probably a month or two away from
>>> submitting this driver again.
>>>
>>> https://urldefense.proofpoint.com/v2/url?u=https-3A__gitlab.collabora.com_chipsnmedia_kernel_-2D_commit_ac59eafd5076c4deb3bfe1fb85b3b776586ef3eb&d=DwIFaQ&c=7dfBJ8cXbWjhc0BhImu8wVIoUFmBzj1s88r8EGyM0UY&r=P4xb2_7biqBxD4LGGPrSV6j-jf3C3xlR7PXU-mLTeZE&m=9eWwqueFnh1yZHTW11j-syNVQvema7iBzNQeX1GKUQwXZ9pm6V4HDL_R2tIYKoOw&s=Ez5AyEYFIAJmC_k00IPO_ImzVdLZjr_veRq1bN4RSNg&e=
>>> https://urldefense.proofpoint.com/v2/url?u=https-3A__gitlab.collabora.com_chipsnmedia_kernel_-2D_commit_5de4fbe0abb20b8e8d862b654f93e3efeb1ef251&d=DwIFaQ&c=7dfBJ8cXbWjhc0BhImu8wVIoUFmBzj1s88r8EGyM0UY&r=P4xb2_7biqBxD4LGGPrSV6j-jf3C3xlR7PXU-mLTeZE&m=9eWwqueFnh1yZHTW11j-syNVQvema7iBzNQeX1GKUQwXZ9pm6V4HDL_R2tIYKoOw&s=tM81gjNe-bTjpjmidZ1sAhiodMh6npcVJNOhMCi1mPo&e=
>>>
>>
>> While I'm not going to NAK this series or those 2 patches if you send
>> them, I'm not really convinced that adding more and more complexity to
>> the mem2mem helpers is a good idea, especially since all of those seem
>> to be only needed by stateful video decoders.
>>
>> The mem2mem framework started as a set of helpers to eliminate boiler
>> plate from simple drivers that always get 1 CAPTURE and 1 OUTPUT buffer,
>> run 1 processing job on them and then return both of the to the userspace
>> and I think it should stay like this.
> 
> Its a bit late to try and bring that argument. It should have been raised couple
> of years ago (before I even started helping with these CODEC). Now that all the
> newly written stately decoders uses this framework, it is logical to keep
> reducing the boiler plate for these too. In my opinion, the job_ready()
> callback, should have been a lot more flexible from the start. And allowing
> driver to make it more powerful does not really add that much complexity.
> 
> Speaking of complexity, driving the output manually (outside of the job
> workqueue) during sequence initialization is a way more complex and risky then
> this. Finally, sticking with 1:1 pattern means encoder, detilers, image
> enhancement reducing framerate, etc. would all be unwelcome to use this. Which
> in short, means no one should even use this.
> 
I think those things are m2m, but it would be hard to present in current 
m2m framework:
1. N:1 compositor(It may be implemented as a loop running 2:1 compositor).
2. AV1 film gain
3. HDR with dynamic meta data to SDR

The video things fix for m2m model could be just a little less complex 
than ISP or camera pipeline. The only difference is just ISP won't have 
multiple contexts running at the same time.
If we could design a model for the video encoder I think we could solve 
the most of problems.
A video encoder would have:
1. input graphics buffer
2. reconstruction graphics buffer
3. motion vector cache buffer(optional)
4. coded bitstream output
5. encoding statistic report
>>
>> I think we're strongly in need of a stateful video decoder framework that
>> would actually address the exact problems that those have rather than
>> bending something that wasn't designed with them in mind to work around the
>> differences.
> 
> The bend is already there, of course I'd be happy to help with any new
> framework. Specially on modern stateless, were there is a need to do better
> scheduling.
I didn't know the schedule problem about stateless codec, are they 
supposed to be in the job queue when the buffers that DPB requests are 
own by the driver and its registers are prepared except the trigger bit?
  Just ping me if you have some effort starting, I don't currently
> have a budget or bandwidth to write new drivers or port existing drivers them on
> a newly written framework.
> 
> Nicolas
> 
> 
> [...]

-- 
Hsia-Jun(Randy) Li

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH 1/2] [RESEND] media: v4l2-mem2mem: allow device run without buf
  2023-07-21  8:56         ` Hsia-Jun Li
@ 2023-07-21 16:22           ` Nicolas Dufresne
  2023-07-24 17:29             ` Randy Li
  0 siblings, 1 reply; 33+ messages in thread
From: Nicolas Dufresne @ 2023-07-21 16:22 UTC (permalink / raw)
  To: Hsia-Jun Li, Tomasz Figa
  Cc: linux-media, ayaka, hans.verkuil, mchehab, laurent.pinchart,
	hiroh, hverkuil, linux-kernel, Sebastian Fricke

Le vendredi 21 juillet 2023 à 16:56 +0800, Hsia-Jun Li a écrit :
> 
> On 7/17/23 22:00, Nicolas Dufresne wrote:
> > CAUTION: Email originated externally, do not click links or open attachments unless you recognize the sender and know the content is safe.
> > 
> > 
> > Le mercredi 12 juillet 2023 à 09:31 +0000, Tomasz Figa a écrit :
> > > On Fri, Jul 07, 2023 at 03:14:23PM -0400, Nicolas Dufresne wrote:
> > > > Hi Randy,
> > > > 
> > > > Le mardi 04 juillet 2023 à 12:00 +0800, Hsia-Jun Li a écrit :
> > > > > From: Randy Li <ayaka@soulik.info>
> > > > > 
> > > > > For the decoder supports Dynamic Resolution Change,
> > > > > we don't need to allocate any CAPTURE or graphics buffer
> > > > > for them at inital CAPTURE setup step.
> > > > > 
> > > > > We need to make the device run or we can't get those
> > > > > metadata.
> > > > > 
> > > > > Signed-off-by: Randy Li <ayaka@soulik.info>
> > > > > ---
> > > > >   drivers/media/v4l2-core/v4l2-mem2mem.c | 5 +++--
> > > > >   1 file changed, 3 insertions(+), 2 deletions(-)
> > > > > 
> > > > > diff --git a/drivers/media/v4l2-core/v4l2-mem2mem.c b/drivers/media/v4l2-core/v4l2-mem2mem.c
> > > > > index 0cc30397fbad..c771aba42015 100644
> > > > > --- a/drivers/media/v4l2-core/v4l2-mem2mem.c
> > > > > +++ b/drivers/media/v4l2-core/v4l2-mem2mem.c
> > > > > @@ -301,8 +301,9 @@ static void __v4l2_m2m_try_queue(struct v4l2_m2m_dev *m2m_dev,
> > > > > 
> > > > >    dprintk("Trying to schedule a job for m2m_ctx: %p\n", m2m_ctx);
> > > > > 
> > > > > - if (!m2m_ctx->out_q_ctx.q.streaming
> > > > > -     || !m2m_ctx->cap_q_ctx.q.streaming) {
> > > > > + if (!(m2m_ctx->out_q_ctx.q.streaming || m2m_ctx->out_q_ctx.buffered)
> > > > > +     || !(m2m_ctx->cap_q_ctx.q.streaming
> > > > > +          || m2m_ctx->cap_q_ctx.buffered)) {
> > > > 
> > > > I have a two atches with similar goals in my wave5 tree. It will be easier to
> > > > upstream with an actual user, though, I'm probably a month or two away from
> > > > submitting this driver again.
> > > > 
> > > > https://urldefense.proofpoint.com/v2/url?u=https-3A__gitlab.collabora.com_chipsnmedia_kernel_-2D_commit_ac59eafd5076c4deb3bfe1fb85b3b776586ef3eb&d=DwIFaQ&c=7dfBJ8cXbWjhc0BhImu8wVIoUFmBzj1s88r8EGyM0UY&r=P4xb2_7biqBxD4LGGPrSV6j-jf3C3xlR7PXU-mLTeZE&m=9eWwqueFnh1yZHTW11j-syNVQvema7iBzNQeX1GKUQwXZ9pm6V4HDL_R2tIYKoOw&s=Ez5AyEYFIAJmC_k00IPO_ImzVdLZjr_veRq1bN4RSNg&e=
> > > > https://urldefense.proofpoint.com/v2/url?u=https-3A__gitlab.collabora.com_chipsnmedia_kernel_-2D_commit_5de4fbe0abb20b8e8d862b654f93e3efeb1ef251&d=DwIFaQ&c=7dfBJ8cXbWjhc0BhImu8wVIoUFmBzj1s88r8EGyM0UY&r=P4xb2_7biqBxD4LGGPrSV6j-jf3C3xlR7PXU-mLTeZE&m=9eWwqueFnh1yZHTW11j-syNVQvema7iBzNQeX1GKUQwXZ9pm6V4HDL_R2tIYKoOw&s=tM81gjNe-bTjpjmidZ1sAhiodMh6npcVJNOhMCi1mPo&e=
> > > > 
> > > 
> > > While I'm not going to NAK this series or those 2 patches if you send
> > > them, I'm not really convinced that adding more and more complexity to
> > > the mem2mem helpers is a good idea, especially since all of those seem
> > > to be only needed by stateful video decoders.
> > > 
> > > The mem2mem framework started as a set of helpers to eliminate boiler
> > > plate from simple drivers that always get 1 CAPTURE and 1 OUTPUT buffer,
> > > run 1 processing job on them and then return both of the to the userspace
> > > and I think it should stay like this.
> > 
> > Its a bit late to try and bring that argument. It should have been raised couple
> > of years ago (before I even started helping with these CODEC). Now that all the
> > newly written stately decoders uses this framework, it is logical to keep
> > reducing the boiler plate for these too. In my opinion, the job_ready()
> > callback, should have been a lot more flexible from the start. And allowing
> > driver to make it more powerful does not really add that much complexity.
> > 
> > Speaking of complexity, driving the output manually (outside of the job
> > workqueue) during sequence initialization is a way more complex and risky then
> > this. Finally, sticking with 1:1 pattern means encoder, detilers, image
> > enhancement reducing framerate, etc. would all be unwelcome to use this. Which
> > in short, means no one should even use this.
> > 
> I think those things are m2m, but it would be hard to present in current 
> m2m framework:
> 1. N:1 compositor(It may be implemented as a loop running 2:1 compositor).

Correct, only SRC/DST/BG type of blitters can be supported for compositing,
which is quite limiting. Currently there is no way to make an N:1 M2M, as M2M
instances are implemented at the video node layer, and not at the MC layer. This
is a entirely new subject and API design space to tackle (same goes for 1:N,
like multi scalers, svc decoders etc.).

> 2. AV1 film gain

For AV1/HEVC film grain, it is handle similar to inline converters and scalers.
The driver secretly allocate the reference frames, and post process into the
user visible buffers. It breaks some assumption made by most protected memory
setup though, as not all allocation is user driven, meaning the decoder needs to
know if its secure or not. Secure memory is a also another API design space to
tackle.

> 3. HDR with dynamic meta data to SDR

True, but easy to design around the stateless model. I'm not worried for these.

> 
> The video things fix for m2m model could be just a little less complex 
> than ISP or camera pipeline. The only difference is just ISP won't have 
> multiple contexts running at the same time.

I thought that having the kernel schedule ISP reprocessing jobs (which requires
instances) would be nice. But this can only be solved after we have solved the
N:N use cases of m2m (with multiple instances).

> If we could design a model for the video encoder I think we could solve 
> the most of problems.
> A video encoder would have:
> 1. input graphics buffer
> 2. reconstruction graphics buffer
> 3. motion vector cache buffer(optional)
> 4. coded bitstream output
> 5. encoding statistic report
> > > 
> > > I think we're strongly in need of a stateful video decoder framework that
> > > would actually address the exact problems that those have rather than
> > > bending something that wasn't designed with them in mind to work around the
> > > differences.
> > 
> > The bend is already there, of course I'd be happy to help with any new
> > framework. Specially on modern stateless, were there is a need to do better
> > scheduling.
> I didn't know the schedule problem about stateless codec, are they 
> supposed to be in the job queue when the buffers that DPB requests are 
> own by the driver and its registers are prepared except the trigger bit?

On RK3588 at least, decoder scheduling is going to be complex. There is an even
number of cores, but when you need to decode 8K, you have to pair two cores
(there is a specific set of cores that are to be paired with). We need a decent
scheduling logic to ensure we don't starve 8K decoding session when there is
multiple smaller resolution session on-going.

On MTK, the entropy decoding (LAT) and the reconstruction (CORE) is split. MTK
vcodec is using multiple workqueues to move jobs around, which is clearly
expensive. Also, the life time of a job is not exactly easy to manage.

On RPi HEVC (not upstream yet, but being worked on), the entropy decoding and
reconstruction is done one the same core, but remains 2 concurrent operation.
Does not impose a complex scheduling issue, but it raised the need for a way to
fully utilize such HW.

This is just some examples of complexity for which the current framework is not
that helpful (even though, its not impossible either).

>   Just ping me if you have some effort starting, I don't currently
> > have a budget or bandwidth to write new drivers or port existing drivers them on
> > a newly written framework.
> > 
> > Nicolas
> > 
> > 
> > [...]
> 


^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH 1/2] [RESEND] media: v4l2-mem2mem: allow device run without buf
  2023-07-21 16:22           ` Nicolas Dufresne
@ 2023-07-24 17:29             ` Randy Li
  0 siblings, 0 replies; 33+ messages in thread
From: Randy Li @ 2023-07-24 17:29 UTC (permalink / raw)
  To: Nicolas Dufresne
  Cc: linux-media, Tomasz Figa, Hsia-Jun Li, hans.verkuil, mchehab,
	laurent.pinchart, hiroh, hverkuil, linux-kernel,
	Sebastian Fricke


On 2023/7/22 00:22, Nicolas Dufresne wrote:
> Le vendredi 21 juillet 2023 à 16:56 +0800, Hsia-Jun Li a écrit :
>> On 7/17/23 22:00, Nicolas Dufresne wrote:
>>> CAUTION: Email originated externally, do not click links or open attachments unless you recognize the sender and know the content is safe.
>>>
>>>
>>> Le mercredi 12 juillet 2023 à 09:31 +0000, Tomasz Figa a écrit :
>>>> On Fri, Jul 07, 2023 at 03:14:23PM -0400, Nicolas Dufresne wrote:
>>>>> Hi Randy,
>>>>>
>>>>> Le mardi 04 juillet 2023 à 12:00 +0800, Hsia-Jun Li a écrit :
>>>>>> From: Randy Li <ayaka@soulik.info>
>>>>>>
>>>>>> For the decoder supports Dynamic Resolution Change,
>>>>>> we don't need to allocate any CAPTURE or graphics buffer
>>>>>> for them at inital CAPTURE setup step.
>>>>>>
>>>>>> We need to make the device run or we can't get those
>>>>>> metadata.
>>>>>>
>>>>>> Signed-off-by: Randy Li <ayaka@soulik.info>
>>>>>> ---
>>>>>>    drivers/media/v4l2-core/v4l2-mem2mem.c | 5 +++--
>>>>>>    1 file changed, 3 insertions(+), 2 deletions(-)
>>>>>>
>>>>>> diff --git a/drivers/media/v4l2-core/v4l2-mem2mem.c b/drivers/media/v4l2-core/v4l2-mem2mem.c
>>>>>> index 0cc30397fbad..c771aba42015 100644
>>>>>> --- a/drivers/media/v4l2-core/v4l2-mem2mem.c
>>>>>> +++ b/drivers/media/v4l2-core/v4l2-mem2mem.c
>>>>>> @@ -301,8 +301,9 @@ static void __v4l2_m2m_try_queue(struct v4l2_m2m_dev *m2m_dev,
>>>>>>
>>>>>>     dprintk("Trying to schedule a job for m2m_ctx: %p\n", m2m_ctx);
>>>>>>
>>>>>> - if (!m2m_ctx->out_q_ctx.q.streaming
>>>>>> -     || !m2m_ctx->cap_q_ctx.q.streaming) {
>>>>>> + if (!(m2m_ctx->out_q_ctx.q.streaming || m2m_ctx->out_q_ctx.buffered)
>>>>>> +     || !(m2m_ctx->cap_q_ctx.q.streaming
>>>>>> +          || m2m_ctx->cap_q_ctx.buffered)) {
>>>>> I have a two atches with similar goals in my wave5 tree. It will be easier to
>>>>> upstream with an actual user, though, I'm probably a month or two away from
>>>>> submitting this driver again.
>>>>>
>>>>> https://urldefense.proofpoint.com/v2/url?u=https-3A__gitlab.collabora.com_chipsnmedia_kernel_-2D_commit_ac59eafd5076c4deb3bfe1fb85b3b776586ef3eb&d=DwIFaQ&c=7dfBJ8cXbWjhc0BhImu8wVIoUFmBzj1s88r8EGyM0UY&r=P4xb2_7biqBxD4LGGPrSV6j-jf3C3xlR7PXU-mLTeZE&m=9eWwqueFnh1yZHTW11j-syNVQvema7iBzNQeX1GKUQwXZ9pm6V4HDL_R2tIYKoOw&s=Ez5AyEYFIAJmC_k00IPO_ImzVdLZjr_veRq1bN4RSNg&e=
>>>>> https://urldefense.proofpoint.com/v2/url?u=https-3A__gitlab.collabora.com_chipsnmedia_kernel_-2D_commit_5de4fbe0abb20b8e8d862b654f93e3efeb1ef251&d=DwIFaQ&c=7dfBJ8cXbWjhc0BhImu8wVIoUFmBzj1s88r8EGyM0UY&r=P4xb2_7biqBxD4LGGPrSV6j-jf3C3xlR7PXU-mLTeZE&m=9eWwqueFnh1yZHTW11j-syNVQvema7iBzNQeX1GKUQwXZ9pm6V4HDL_R2tIYKoOw&s=tM81gjNe-bTjpjmidZ1sAhiodMh6npcVJNOhMCi1mPo&e=
>>>>>
>>>> While I'm not going to NAK this series or those 2 patches if you send
>>>> them, I'm not really convinced that adding more and more complexity to
>>>> the mem2mem helpers is a good idea, especially since all of those seem
>>>> to be only needed by stateful video decoders.
>>>>
>>>> The mem2mem framework started as a set of helpers to eliminate boiler
>>>> plate from simple drivers that always get 1 CAPTURE and 1 OUTPUT buffer,
>>>> run 1 processing job on them and then return both of the to the userspace
>>>> and I think it should stay like this.
>>> Its a bit late to try and bring that argument. It should have been raised couple
>>> of years ago (before I even started helping with these CODEC). Now that all the
>>> newly written stately decoders uses this framework, it is logical to keep
>>> reducing the boiler plate for these too. In my opinion, the job_ready()
>>> callback, should have been a lot more flexible from the start. And allowing
>>> driver to make it more powerful does not really add that much complexity.
>>>
>>> Speaking of complexity, driving the output manually (outside of the job
>>> workqueue) during sequence initialization is a way more complex and risky then
>>> this. Finally, sticking with 1:1 pattern means encoder, detilers, image
>>> enhancement reducing framerate, etc. would all be unwelcome to use this. Which
>>> in short, means no one should even use this.
>>>
>> I think those things are m2m, but it would be hard to present in current
>> m2m framework:
>> 1. N:1 compositor(It may be implemented as a loop running 2:1 compositor).
> Correct, only SRC/DST/BG type of blitters can be supported for compositing,
> which is quite limiting. Currently there is no way to make an N:1 M2M, as M2M
> instances are implemented at the video node layer, and not at the MC layer. This
> is a entirely new subject and API design space to tackle (same goes for 1:N,
> like multi scalers, svc decoders etc.).
SVC case is the one I mention in the talk, although the major problem 
may only happens to SVC-S.
>
>> 2. AV1 film gain
> For AV1/HEVC film grain, it is handle similar to inline converters and scalers.

I know a few decoders in the market didn't implement such feature in the 
its hardware, they rely on the other hardware.

Actually, it would be better to let NPU do such job.

> The driver secretly allocate the reference frames, and post process into the
> user visible buffers.
Hiding internal buffer is the worst case, frame buffer could be large.
> It breaks some assumption made by most protected memory
> setup though, as not all allocation is user driven, meaning the decoder needs to
> know if its secure or not. Secure memory is a also another API design space to
> tackle.
>
>> 3. HDR with dynamic meta data to SDR
> True, but easy to design around the stateless model. I'm not worried for these.
The current stateless API won't support DMA buffer for the metadata.
>
>> The video things fix for m2m model could be just a little less complex
>> than ISP or camera pipeline. The only difference is just ISP won't have
>> multiple contexts running at the same time.
> I thought that having the kernel schedule ISP reprocessing jobs (which requires
> instances) would be nice. But this can only be solved after we have solved the
> N:N use cases of m2m (with multiple instances).
>
>> If we could design a model for the video encoder I think we could solve
>> the most of problems.
>> A video encoder would have:
>> 1. input graphics buffer
>> 2. reconstruction graphics buffer
>> 3. motion vector cache buffer(optional)
>> 4. coded bitstream output
>> 5. encoding statistic report
>>>> I think we're strongly in need of a stateful video decoder framework that
>>>> would actually address the exact problems that those have rather than
>>>> bending something that wasn't designed with them in mind to work around the
>>>> differences.
>>> The bend is already there, of course I'd be happy to help with any new
>>> framework. Specially on modern stateless, were there is a need to do better
>>> scheduling.
>> I didn't know the schedule problem about stateless codec, are they
>> supposed to be in the job queue when the buffers that DPB requests are
>> own by the driver and its registers are prepared except the trigger bit?
> On RK3588 at least, decoder scheduling is going to be complex. There is an even
> number of cores, but when you need to decode 8K, you have to pair two cores
> (there is a specific set of cores that are to be paired with). We need a decent

How do two cores work parallel? Tiles ?

But AV1 could do intra block copy.

> scheduling logic to ensure we don't starve 8K decoding session when there is
> multiple smaller resolution session on-going.
>
> On MTK, the entropy decoding (LAT) and the reconstruction (CORE) is split. MTK
> vcodec is using multiple workqueues to move jobs around, which is clearly
> expensive. Also, the life time of a job is not exactly easy to manage.

This model sounds easy,

LAT produces partial frame buffer with intra blocks and its motion 
vector buffer

CORE complete the frame from the motion vector buffer and its reference 
buffers

We just separately two hardware devices here.

>
> On RPi HEVC (not upstream yet, but being worked on), the entropy decoding and
> reconstruction is done one the same core, but remains 2 concurrent operation.
> Does not impose a complex scheduling issue, but it raised the need for a way to
> fully utilize such HW.

This sounds be more complex than MTK's case. It would be hard to measure 
the job length with entropy part and inter construction part.

Although usually the later one would consume more memory bandwidth or 
hardware time.

>
> This is just some examples of complexity for which the current framework is not
> that helpful (even though, its not impossible either).
>
>>    Just ping me if you have some effort starting, I don't currently
>>> have a budget or bandwidth to write new drivers or port existing drivers them on
>>> a newly written framework.
>>>
>>> Nicolas
>>>
>>>
>>> [...]

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH 2/2] media: v4l2-mem2mem: add a list for buf used by hw
  2023-07-17  7:14     ` Hsia-Jun Li
@ 2023-07-27  7:25       ` Tomasz Figa
  2023-07-27  7:33         ` Hsia-Jun Li
  0 siblings, 1 reply; 33+ messages in thread
From: Tomasz Figa @ 2023-07-27  7:25 UTC (permalink / raw)
  To: Hsia-Jun Li
  Cc: linux-media, ayaka, hans.verkuil, mchehab, laurent.pinchart,
	hiroh, hverkuil, linux-kernel, nicolas

On Mon, Jul 17, 2023 at 4:15 PM Hsia-Jun Li <Randy.Li@synaptics.com> wrote:
>
>
> On 7/12/23 17:33, Tomasz Figa wrote:
> > CAUTION: Email originated externally, do not click links or open attachments unless you recognize the sender and know the content is safe.
> >
> >
> > On Tue, Jul 04, 2023 at 12:00:38PM +0800, Hsia-Jun Li wrote:
> >> From: "Hsia-Jun(Randy) Li" <randy.li@synaptics.com>
> >>
> >> Many drivers have to create its own buf_struct for a
> >> vb2_queue to track such a state. Also driver has to
> >> iterate over rdy_queue every times to find out a buffer
> >> which is not sent to hardware(or firmware), this new
> >> list just offers the driver a place to store the buffer
> >> that hardware(firmware) has acknowledged.
> >>
> >> One important advance about this list, it doesn't like
> >> rdy_queue which both bottom half of the user calling
> >> could operate it, while the v4l2 worker would as well.
> >> The v4l2 core could only operate this queue when its
> >> v4l2_context is not running, the driver would only
> >> access this new hw_queue in its own worker.
> > Could you describe in what case such a list would be useful for a
> > mem2mem driver?
>
> This list, as its description, just for saving us from creating a
> private buffer struct to track buffer state.
>
> The queue in the kernel is not the queue that hardware(codec firmware)
> are using.
>

Sorry, I find the description difficult to understand. It might make
sense to have the text proofread by someone experienced in writing
technical documentation in English before posting in the future.
Thanks.

I think I got the point from Nicolas' explanation, though.

>
> >> Signed-off-by: Hsia-Jun(Randy) Li <randy.li@synaptics.com>
> >> ---
> >>   drivers/media/v4l2-core/v4l2-mem2mem.c | 25 +++++++++++++++++--------
> >>   include/media/v4l2-mem2mem.h           | 10 +++++++++-
> >>   2 files changed, 26 insertions(+), 9 deletions(-)
> >>
> >> diff --git a/drivers/media/v4l2-core/v4l2-mem2mem.c b/drivers/media/v4l2-core/v4l2-mem2mem.c
> >> index c771aba42015..b4151147d5bd 100644
> >> --- a/drivers/media/v4l2-core/v4l2-mem2mem.c
> >> +++ b/drivers/media/v4l2-core/v4l2-mem2mem.c
> >> @@ -321,15 +321,21 @@ static void __v4l2_m2m_try_queue(struct v4l2_m2m_dev *m2m_dev,
> >>                goto job_unlock;
> >>        }
> >>
> >> -     src = v4l2_m2m_next_src_buf(m2m_ctx);
> >> -     dst = v4l2_m2m_next_dst_buf(m2m_ctx);
> >> -     if (!src && !m2m_ctx->out_q_ctx.buffered) {
> >> -             dprintk("No input buffers available\n");
> >> -             goto job_unlock;
> >> +     if (list_empty(&m2m_ctx->out_q_ctx.hw_queue)) {
> >> +             src = v4l2_m2m_next_src_buf(m2m_ctx);
> >> +
> >> +             if (!src && !m2m_ctx->out_q_ctx.buffered) {
> >> +                     dprintk("No input buffers available\n");
> >> +                     goto job_unlock;
> >> +             }
> >>        }
> >> -     if (!dst && !m2m_ctx->cap_q_ctx.buffered) {
> >> -             dprintk("No output buffers available\n");
> >> -             goto job_unlock;
> >> +
> >> +     if (list_empty(&m2m_ctx->cap_q_ctx.hw_queue)) {
> >> +             dst = v4l2_m2m_next_dst_buf(m2m_ctx);
> >> +             if (!dst && !m2m_ctx->cap_q_ctx.buffered) {
> >> +                     dprintk("No output buffers available\n");
> >> +                     goto job_unlock;
> >> +             }
> >>        }
> > src and dst would be referenced unitialized below if neither of the
> > above ifs hits...
> I think they have been initialized at v4l2_m2m_ctx_init()

What do you mean? They are local variables in this function.

> >
> > Best regards,
> > Tomasz
> >
> >>        m2m_ctx->new_frame = true;
> >> @@ -896,6 +902,7 @@ int v4l2_m2m_streamoff(struct file *file, struct v4l2_m2m_ctx *m2m_ctx,
> >>        INIT_LIST_HEAD(&q_ctx->rdy_queue);
> >>        q_ctx->num_rdy = 0;
> >>        spin_unlock_irqrestore(&q_ctx->rdy_spinlock, flags);
> >> +     INIT_LIST_HEAD(&q_ctx->hw_queue);
> >>
> >>        if (m2m_dev->curr_ctx == m2m_ctx) {
> >>                m2m_dev->curr_ctx = NULL;
> >> @@ -1234,6 +1241,8 @@ struct v4l2_m2m_ctx *v4l2_m2m_ctx_init(struct v4l2_m2m_dev *m2m_dev,
> >>
> >>        INIT_LIST_HEAD(&out_q_ctx->rdy_queue);
> >>        INIT_LIST_HEAD(&cap_q_ctx->rdy_queue);
> >> +     INIT_LIST_HEAD(&out_q_ctx->hw_queue);
> >> +     INIT_LIST_HEAD(&cap_q_ctx->hw_queue);
> >>        spin_lock_init(&out_q_ctx->rdy_spinlock);
> >>        spin_lock_init(&cap_q_ctx->rdy_spinlock);
> >>
> >> diff --git a/include/media/v4l2-mem2mem.h b/include/media/v4l2-mem2mem.h
> >> index d6c8eb2b5201..2342656e582d 100644
> >> --- a/include/media/v4l2-mem2mem.h
> >> +++ b/include/media/v4l2-mem2mem.h
> >> @@ -53,9 +53,16 @@ struct v4l2_m2m_dev;
> >>    *   processed
> >>    *
> >>    * @q:               pointer to struct &vb2_queue
> >> - * @rdy_queue:       List of V4L2 mem-to-mem queues
> >> + * @rdy_queue:       List of V4L2 mem-to-mem queues. If v4l2_m2m_buf_queue() is
> >> + *           called in struct vb2_ops->buf_queue(), the buffer enqueued
> >> + *           by user would be added to this list.
> >>    * @rdy_spinlock: spin lock to protect the struct usage
> >>    * @num_rdy: number of buffers ready to be processed
> >> + * @hw_queue:        A list for tracking the buffer is occupied by the hardware
> >> + *           (or device's firmware). A buffer could only be in either
> >> + *           this list or @rdy_queue.
> >> + *           Driver may choose not to use this list while uses its own
> >> + *           private data to do this work.
> >>    * @buffered:        is the queue buffered?
> >>    *
> >>    * Queue for buffers ready to be processed as soon as this
> >> @@ -68,6 +75,7 @@ struct v4l2_m2m_queue_ctx {
> >>        struct list_head        rdy_queue;
> >>        spinlock_t              rdy_spinlock;
> >>        u8                      num_rdy;
> >> +     struct list_head        hw_queue;
> >>        bool                    buffered;
> >>   };
> >>
> >> --
> >> 2.17.1
> >>
> --
> Hsia-Jun(Randy) Li
>

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH 2/2] media: v4l2-mem2mem: add a list for buf used by hw
  2023-07-27  7:25       ` Tomasz Figa
@ 2023-07-27  7:33         ` Hsia-Jun Li
  2023-07-27  7:54           ` Tomasz Figa
  0 siblings, 1 reply; 33+ messages in thread
From: Hsia-Jun Li @ 2023-07-27  7:33 UTC (permalink / raw)
  To: Tomasz Figa
  Cc: linux-media, ayaka, hans.verkuil, mchehab, laurent.pinchart,
	hiroh, hverkuil, linux-kernel, nicolas



On 7/27/23 15:25, Tomasz Figa wrote:
> CAUTION: Email originated externally, do not click links or open attachments unless you recognize the sender and know the content is safe.
> 
> 
> On Mon, Jul 17, 2023 at 4:15 PM Hsia-Jun Li <Randy.Li@synaptics.com> wrote:
>>
>>
>> On 7/12/23 17:33, Tomasz Figa wrote:
>>> CAUTION: Email originated externally, do not click links or open attachments unless you recognize the sender and know the content is safe.
>>>
>>>
>>> On Tue, Jul 04, 2023 at 12:00:38PM +0800, Hsia-Jun Li wrote:
>>>> From: "Hsia-Jun(Randy) Li" <randy.li@synaptics.com>
>>>>
>>>> Many drivers have to create its own buf_struct for a
>>>> vb2_queue to track such a state. Also driver has to
>>>> iterate over rdy_queue every times to find out a buffer
>>>> which is not sent to hardware(or firmware), this new
>>>> list just offers the driver a place to store the buffer
>>>> that hardware(firmware) has acknowledged.
>>>>
>>>> One important advance about this list, it doesn't like
>>>> rdy_queue which both bottom half of the user calling
>>>> could operate it, while the v4l2 worker would as well.
>>>> The v4l2 core could only operate this queue when its
>>>> v4l2_context is not running, the driver would only
>>>> access this new hw_queue in its own worker.
>>> Could you describe in what case such a list would be useful for a
>>> mem2mem driver?
>>
>> This list, as its description, just for saving us from creating a
>> private buffer struct to track buffer state.
>>
>> The queue in the kernel is not the queue that hardware(codec firmware)
>> are using.
>>
> 
> Sorry, I find the description difficult to understand. It might make
> sense to have the text proofread by someone experienced in writing
> technical documentation in English before posting in the future.
> Thanks.
> 
Sorry, I may not be able to get more resource here. I would try to ask a 
chatbot to fix my description next time.
> I think I got the point from Nicolas' explanation, though.
> 
>>
>>>> Signed-off-by: Hsia-Jun(Randy) Li <randy.li@synaptics.com>
>>>> ---
>>>>    drivers/media/v4l2-core/v4l2-mem2mem.c | 25 +++++++++++++++++--------
>>>>    include/media/v4l2-mem2mem.h           | 10 +++++++++-
>>>>    2 files changed, 26 insertions(+), 9 deletions(-)
>>>>
>>>> diff --git a/drivers/media/v4l2-core/v4l2-mem2mem.c b/drivers/media/v4l2-core/v4l2-mem2mem.c
>>>> index c771aba42015..b4151147d5bd 100644
>>>> --- a/drivers/media/v4l2-core/v4l2-mem2mem.c
>>>> +++ b/drivers/media/v4l2-core/v4l2-mem2mem.c
>>>> @@ -321,15 +321,21 @@ static void __v4l2_m2m_try_queue(struct v4l2_m2m_dev *m2m_dev,
>>>>                 goto job_unlock;
>>>>         }
>>>>
>>>> -     src = v4l2_m2m_next_src_buf(m2m_ctx);
>>>> -     dst = v4l2_m2m_next_dst_buf(m2m_ctx);
>>>> -     if (!src && !m2m_ctx->out_q_ctx.buffered) {
>>>> -             dprintk("No input buffers available\n");
>>>> -             goto job_unlock;
>>>> +     if (list_empty(&m2m_ctx->out_q_ctx.hw_queue)) {
>>>> +             src = v4l2_m2m_next_src_buf(m2m_ctx);
>>>> +
>>>> +             if (!src && !m2m_ctx->out_q_ctx.buffered) {
>>>> +                     dprintk("No input buffers available\n");
>>>> +                     goto job_unlock;
>>>> +             }
>>>>         }
>>>> -     if (!dst && !m2m_ctx->cap_q_ctx.buffered) {
>>>> -             dprintk("No output buffers available\n");
>>>> -             goto job_unlock;
>>>> +
>>>> +     if (list_empty(&m2m_ctx->cap_q_ctx.hw_queue)) {
>>>> +             dst = v4l2_m2m_next_dst_buf(m2m_ctx);
>>>> +             if (!dst && !m2m_ctx->cap_q_ctx.buffered) {
>>>> +                     dprintk("No output buffers available\n");
>>>> +                     goto job_unlock;
>>>> +             }
>>>>         }
>>> src and dst would be referenced unitialized below if neither of the
>>> above ifs hits...
>> I think they have been initialized at v4l2_m2m_ctx_init()
> 
> What do you mean? They are local variables in this function.
> 
Sorry, I didn't notice the sentence after that.
>>>
>>> Best regards,
>>> Tomasz
>>>
>>>>         m2m_ctx->new_frame = true;
>>>> @@ -896,6 +902,7 @@ int v4l2_m2m_streamoff(struct file *file, struct v4l2_m2m_ctx *m2m_ctx,
>>>>         INIT_LIST_HEAD(&q_ctx->rdy_queue);
>>>>         q_ctx->num_rdy = 0;
>>>>         spin_unlock_irqrestore(&q_ctx->rdy_spinlock, flags);
>>>> +     INIT_LIST_HEAD(&q_ctx->hw_queue);
>>>>
>>>>         if (m2m_dev->curr_ctx == m2m_ctx) {
>>>>                 m2m_dev->curr_ctx = NULL;
>>>> @@ -1234,6 +1241,8 @@ struct v4l2_m2m_ctx *v4l2_m2m_ctx_init(struct v4l2_m2m_dev *m2m_dev,
>>>>
>>>>         INIT_LIST_HEAD(&out_q_ctx->rdy_queue);
>>>>         INIT_LIST_HEAD(&cap_q_ctx->rdy_queue);
>>>> +     INIT_LIST_HEAD(&out_q_ctx->hw_queue);
>>>> +     INIT_LIST_HEAD(&cap_q_ctx->hw_queue);
>>>>         spin_lock_init(&out_q_ctx->rdy_spinlock);
>>>>         spin_lock_init(&cap_q_ctx->rdy_spinlock);
>>>>
>>>> diff --git a/include/media/v4l2-mem2mem.h b/include/media/v4l2-mem2mem.h
>>>> index d6c8eb2b5201..2342656e582d 100644
>>>> --- a/include/media/v4l2-mem2mem.h
>>>> +++ b/include/media/v4l2-mem2mem.h
>>>> @@ -53,9 +53,16 @@ struct v4l2_m2m_dev;
>>>>     *   processed
>>>>     *
>>>>     * @q:               pointer to struct &vb2_queue
>>>> - * @rdy_queue:       List of V4L2 mem-to-mem queues
>>>> + * @rdy_queue:       List of V4L2 mem-to-mem queues. If v4l2_m2m_buf_queue() is
>>>> + *           called in struct vb2_ops->buf_queue(), the buffer enqueued
>>>> + *           by user would be added to this list.
>>>>     * @rdy_spinlock: spin lock to protect the struct usage
>>>>     * @num_rdy: number of buffers ready to be processed
>>>> + * @hw_queue:        A list for tracking the buffer is occupied by the hardware
>>>> + *           (or device's firmware). A buffer could only be in either
>>>> + *           this list or @rdy_queue.
>>>> + *           Driver may choose not to use this list while uses its own
>>>> + *           private data to do this work.
>>>>     * @buffered:        is the queue buffered?
>>>>     *
>>>>     * Queue for buffers ready to be processed as soon as this
>>>> @@ -68,6 +75,7 @@ struct v4l2_m2m_queue_ctx {
>>>>         struct list_head        rdy_queue;
>>>>         spinlock_t              rdy_spinlock;
>>>>         u8                      num_rdy;
>>>> +     struct list_head        hw_queue;
>>>>         bool                    buffered;
>>>>    };
>>>>
>>>> --
>>>> 2.17.1
>>>>
>> --
>> Hsia-Jun(Randy) Li
>>

-- 
Hsia-Jun(Randy) Li

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH 2/2] media: v4l2-mem2mem: add a list for buf used by hw
  2023-07-17 14:07     ` Nicolas Dufresne
  2023-07-18  3:53       ` Hsia-Jun Li
@ 2023-07-27  7:43       ` Tomasz Figa
  2023-07-27 16:58         ` Nicolas Dufresne
  1 sibling, 1 reply; 33+ messages in thread
From: Tomasz Figa @ 2023-07-27  7:43 UTC (permalink / raw)
  To: Nicolas Dufresne
  Cc: Hsia-Jun Li, linux-media, ayaka, hans.verkuil, mchehab,
	laurent.pinchart, hiroh, hverkuil, linux-kernel

On Mon, Jul 17, 2023 at 11:07 PM Nicolas Dufresne <nicolas@ndufresne.ca> wrote:
>
> Le mercredi 12 juillet 2023 à 09:33 +0000, Tomasz Figa a écrit :
> > On Tue, Jul 04, 2023 at 12:00:38PM +0800, Hsia-Jun Li wrote:
> > > From: "Hsia-Jun(Randy) Li" <randy.li@synaptics.com>
> > >
> > > Many drivers have to create its own buf_struct for a
> > > vb2_queue to track such a state. Also driver has to
> > > iterate over rdy_queue every times to find out a buffer
> > > which is not sent to hardware(or firmware), this new
> > > list just offers the driver a place to store the buffer
> > > that hardware(firmware) has acknowledged.
> > >
> > > One important advance about this list, it doesn't like
> > > rdy_queue which both bottom half of the user calling
> > > could operate it, while the v4l2 worker would as well.
> > > The v4l2 core could only operate this queue when its
> > > v4l2_context is not running, the driver would only
> > > access this new hw_queue in its own worker.
> >
> > Could you describe in what case such a list would be useful for a
> > mem2mem driver?
>
> Today all driver must track buffers that are "owned by the hardware". This is a
> concept dictated by the m2m framework and enforced through the ACTIVE flag. All
> buffers from this list must be mark as done/error/queued after streamoff of the
> respective queue in order to acknowledge that they are no longer in use by the
> HW. Not doing so will warn:
>
>   videobuf2_common: driver bug: stop_streaming operation is leaving buf ...
>
> Though, there is no queue to easily iterate them. All driver endup having their
> own queue, or just leaving the buffers in the rdy_queue (which isn't better).
>

Thanks for the explanation. I see how it could be useful now.

Although I guess this is a problem specifically for hardware (or
firmware) which can internally queue more than 1 buffer, right?
Otherwise the current buffer could just stay at the top of the
rdy_queue until it's removed by the driver's completion handler,
timeout/error handler or context destruction.

Best regards,
Tomasz

> Nicolas
> >
> > >
> > > Signed-off-by: Hsia-Jun(Randy) Li <randy.li@synaptics.com>
> > > ---
> > >  drivers/media/v4l2-core/v4l2-mem2mem.c | 25 +++++++++++++++++--------
> > >  include/media/v4l2-mem2mem.h           | 10 +++++++++-
> > >  2 files changed, 26 insertions(+), 9 deletions(-)
> > >
> > > diff --git a/drivers/media/v4l2-core/v4l2-mem2mem.c b/drivers/media/v4l2-core/v4l2-mem2mem.c
> > > index c771aba42015..b4151147d5bd 100644
> > > --- a/drivers/media/v4l2-core/v4l2-mem2mem.c
> > > +++ b/drivers/media/v4l2-core/v4l2-mem2mem.c
> > > @@ -321,15 +321,21 @@ static void __v4l2_m2m_try_queue(struct v4l2_m2m_dev *m2m_dev,
> > >             goto job_unlock;
> > >     }
> > >
> > > -   src = v4l2_m2m_next_src_buf(m2m_ctx);
> > > -   dst = v4l2_m2m_next_dst_buf(m2m_ctx);
> > > -   if (!src && !m2m_ctx->out_q_ctx.buffered) {
> > > -           dprintk("No input buffers available\n");
> > > -           goto job_unlock;
> > > +   if (list_empty(&m2m_ctx->out_q_ctx.hw_queue)) {
> > > +           src = v4l2_m2m_next_src_buf(m2m_ctx);
> > > +
> > > +           if (!src && !m2m_ctx->out_q_ctx.buffered) {
> > > +                   dprintk("No input buffers available\n");
> > > +                   goto job_unlock;
> > > +           }
> > >     }
> > > -   if (!dst && !m2m_ctx->cap_q_ctx.buffered) {
> > > -           dprintk("No output buffers available\n");
> > > -           goto job_unlock;
> > > +
> > > +   if (list_empty(&m2m_ctx->cap_q_ctx.hw_queue)) {
> > > +           dst = v4l2_m2m_next_dst_buf(m2m_ctx);
> > > +           if (!dst && !m2m_ctx->cap_q_ctx.buffered) {
> > > +                   dprintk("No output buffers available\n");
> > > +                   goto job_unlock;
> > > +           }
> > >     }
> >
> > src and dst would be referenced unitialized below if neither of the
> > above ifs hits...
> >
> > Best regards,
> > Tomasz
> >
> > >
> > >     m2m_ctx->new_frame = true;
> > > @@ -896,6 +902,7 @@ int v4l2_m2m_streamoff(struct file *file, struct v4l2_m2m_ctx *m2m_ctx,
> > >     INIT_LIST_HEAD(&q_ctx->rdy_queue);
> > >     q_ctx->num_rdy = 0;
> > >     spin_unlock_irqrestore(&q_ctx->rdy_spinlock, flags);
> > > +   INIT_LIST_HEAD(&q_ctx->hw_queue);
> > >
> > >     if (m2m_dev->curr_ctx == m2m_ctx) {
> > >             m2m_dev->curr_ctx = NULL;
> > > @@ -1234,6 +1241,8 @@ struct v4l2_m2m_ctx *v4l2_m2m_ctx_init(struct v4l2_m2m_dev *m2m_dev,
> > >
> > >     INIT_LIST_HEAD(&out_q_ctx->rdy_queue);
> > >     INIT_LIST_HEAD(&cap_q_ctx->rdy_queue);
> > > +   INIT_LIST_HEAD(&out_q_ctx->hw_queue);
> > > +   INIT_LIST_HEAD(&cap_q_ctx->hw_queue);
> > >     spin_lock_init(&out_q_ctx->rdy_spinlock);
> > >     spin_lock_init(&cap_q_ctx->rdy_spinlock);
> > >
> > > diff --git a/include/media/v4l2-mem2mem.h b/include/media/v4l2-mem2mem.h
> > > index d6c8eb2b5201..2342656e582d 100644
> > > --- a/include/media/v4l2-mem2mem.h
> > > +++ b/include/media/v4l2-mem2mem.h
> > > @@ -53,9 +53,16 @@ struct v4l2_m2m_dev;
> > >   * processed
> > >   *
> > >   * @q:             pointer to struct &vb2_queue
> > > - * @rdy_queue:     List of V4L2 mem-to-mem queues
> > > + * @rdy_queue:     List of V4L2 mem-to-mem queues. If v4l2_m2m_buf_queue() is
> > > + *         called in struct vb2_ops->buf_queue(), the buffer enqueued
> > > + *         by user would be added to this list.
> > >   * @rdy_spinlock: spin lock to protect the struct usage
> > >   * @num_rdy:       number of buffers ready to be processed
> > > + * @hw_queue:      A list for tracking the buffer is occupied by the hardware
> > > + *                 (or device's firmware). A buffer could only be in either
> > > + *                 this list or @rdy_queue.
> > > + *                 Driver may choose not to use this list while uses its own
> > > + *                 private data to do this work.
> > >   * @buffered:      is the queue buffered?
> > >   *
> > >   * Queue for buffers ready to be processed as soon as this
> > > @@ -68,6 +75,7 @@ struct v4l2_m2m_queue_ctx {
> > >     struct list_head        rdy_queue;
> > >     spinlock_t              rdy_spinlock;
> > >     u8                      num_rdy;
> > > +   struct list_head        hw_queue;
> > >     bool                    buffered;
> > >  };
> > >
> > > --
> > > 2.17.1
> > >
>

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH 2/2] media: v4l2-mem2mem: add a list for buf used by hw
  2023-07-27  7:33         ` Hsia-Jun Li
@ 2023-07-27  7:54           ` Tomasz Figa
  0 siblings, 0 replies; 33+ messages in thread
From: Tomasz Figa @ 2023-07-27  7:54 UTC (permalink / raw)
  To: Hsia-Jun Li
  Cc: linux-media, ayaka, hans.verkuil, mchehab, laurent.pinchart,
	hiroh, hverkuil, linux-kernel, nicolas

On Thu, Jul 27, 2023 at 4:33 PM Hsia-Jun Li <Randy.Li@synaptics.com> wrote:
>
>
>
> On 7/27/23 15:25, Tomasz Figa wrote:
> > CAUTION: Email originated externally, do not click links or open attachments unless you recognize the sender and know the content is safe.
> >
> >
> > On Mon, Jul 17, 2023 at 4:15 PM Hsia-Jun Li <Randy.Li@synaptics.com> wrote:
> >>
> >>
> >> On 7/12/23 17:33, Tomasz Figa wrote:
> >>> CAUTION: Email originated externally, do not click links or open attachments unless you recognize the sender and know the content is safe.
> >>>
> >>>
> >>> On Tue, Jul 04, 2023 at 12:00:38PM +0800, Hsia-Jun Li wrote:
> >>>> From: "Hsia-Jun(Randy) Li" <randy.li@synaptics.com>
> >>>>
> >>>> Many drivers have to create its own buf_struct for a
> >>>> vb2_queue to track such a state. Also driver has to
> >>>> iterate over rdy_queue every times to find out a buffer
> >>>> which is not sent to hardware(or firmware), this new
> >>>> list just offers the driver a place to store the buffer
> >>>> that hardware(firmware) has acknowledged.
> >>>>
> >>>> One important advance about this list, it doesn't like
> >>>> rdy_queue which both bottom half of the user calling
> >>>> could operate it, while the v4l2 worker would as well.
> >>>> The v4l2 core could only operate this queue when its
> >>>> v4l2_context is not running, the driver would only
> >>>> access this new hw_queue in its own worker.
> >>> Could you describe in what case such a list would be useful for a
> >>> mem2mem driver?
> >>
> >> This list, as its description, just for saving us from creating a
> >> private buffer struct to track buffer state.
> >>
> >> The queue in the kernel is not the queue that hardware(codec firmware)
> >> are using.
> >>
> >
> > Sorry, I find the description difficult to understand. It might make
> > sense to have the text proofread by someone experienced in writing
> > technical documentation in English before posting in the future.
> > Thanks.
> >
> Sorry, I may not be able to get more resource here. I would try to ask a
> chatbot to fix my description next time.

I think people on the linux-media IRC channel (including me) could
also be willing to help with rephrasing things, but if a chatbot can
do it too, it's even better. :)

> > I think I got the point from Nicolas' explanation, though.
> >
> >>
> >>>> Signed-off-by: Hsia-Jun(Randy) Li <randy.li@synaptics.com>
> >>>> ---
> >>>>    drivers/media/v4l2-core/v4l2-mem2mem.c | 25 +++++++++++++++++--------
> >>>>    include/media/v4l2-mem2mem.h           | 10 +++++++++-
> >>>>    2 files changed, 26 insertions(+), 9 deletions(-)
> >>>>
> >>>> diff --git a/drivers/media/v4l2-core/v4l2-mem2mem.c b/drivers/media/v4l2-core/v4l2-mem2mem.c
> >>>> index c771aba42015..b4151147d5bd 100644
> >>>> --- a/drivers/media/v4l2-core/v4l2-mem2mem.c
> >>>> +++ b/drivers/media/v4l2-core/v4l2-mem2mem.c
> >>>> @@ -321,15 +321,21 @@ static void __v4l2_m2m_try_queue(struct v4l2_m2m_dev *m2m_dev,
> >>>>                 goto job_unlock;
> >>>>         }
> >>>>
> >>>> -     src = v4l2_m2m_next_src_buf(m2m_ctx);
> >>>> -     dst = v4l2_m2m_next_dst_buf(m2m_ctx);
> >>>> -     if (!src && !m2m_ctx->out_q_ctx.buffered) {
> >>>> -             dprintk("No input buffers available\n");
> >>>> -             goto job_unlock;
> >>>> +     if (list_empty(&m2m_ctx->out_q_ctx.hw_queue)) {
> >>>> +             src = v4l2_m2m_next_src_buf(m2m_ctx);
> >>>> +
> >>>> +             if (!src && !m2m_ctx->out_q_ctx.buffered) {
> >>>> +                     dprintk("No input buffers available\n");
> >>>> +                     goto job_unlock;
> >>>> +             }
> >>>>         }
> >>>> -     if (!dst && !m2m_ctx->cap_q_ctx.buffered) {
> >>>> -             dprintk("No output buffers available\n");
> >>>> -             goto job_unlock;
> >>>> +
> >>>> +     if (list_empty(&m2m_ctx->cap_q_ctx.hw_queue)) {
> >>>> +             dst = v4l2_m2m_next_dst_buf(m2m_ctx);
> >>>> +             if (!dst && !m2m_ctx->cap_q_ctx.buffered) {
> >>>> +                     dprintk("No output buffers available\n");
> >>>> +                     goto job_unlock;
> >>>> +             }
> >>>>         }
> >>> src and dst would be referenced unitialized below if neither of the
> >>> above ifs hits...
> >> I think they have been initialized at v4l2_m2m_ctx_init()
> >
> > What do you mean? They are local variables in this function.
> >
> Sorry, I didn't notice the sentence after that.
> >>>
> >>> Best regards,
> >>> Tomasz
> >>>
> >>>>         m2m_ctx->new_frame = true;
> >>>> @@ -896,6 +902,7 @@ int v4l2_m2m_streamoff(struct file *file, struct v4l2_m2m_ctx *m2m_ctx,
> >>>>         INIT_LIST_HEAD(&q_ctx->rdy_queue);
> >>>>         q_ctx->num_rdy = 0;
> >>>>         spin_unlock_irqrestore(&q_ctx->rdy_spinlock, flags);
> >>>> +     INIT_LIST_HEAD(&q_ctx->hw_queue);
> >>>>
> >>>>         if (m2m_dev->curr_ctx == m2m_ctx) {
> >>>>                 m2m_dev->curr_ctx = NULL;
> >>>> @@ -1234,6 +1241,8 @@ struct v4l2_m2m_ctx *v4l2_m2m_ctx_init(struct v4l2_m2m_dev *m2m_dev,
> >>>>
> >>>>         INIT_LIST_HEAD(&out_q_ctx->rdy_queue);
> >>>>         INIT_LIST_HEAD(&cap_q_ctx->rdy_queue);
> >>>> +     INIT_LIST_HEAD(&out_q_ctx->hw_queue);
> >>>> +     INIT_LIST_HEAD(&cap_q_ctx->hw_queue);
> >>>>         spin_lock_init(&out_q_ctx->rdy_spinlock);
> >>>>         spin_lock_init(&cap_q_ctx->rdy_spinlock);
> >>>>
> >>>> diff --git a/include/media/v4l2-mem2mem.h b/include/media/v4l2-mem2mem.h
> >>>> index d6c8eb2b5201..2342656e582d 100644
> >>>> --- a/include/media/v4l2-mem2mem.h
> >>>> +++ b/include/media/v4l2-mem2mem.h
> >>>> @@ -53,9 +53,16 @@ struct v4l2_m2m_dev;
> >>>>     *   processed
> >>>>     *
> >>>>     * @q:               pointer to struct &vb2_queue
> >>>> - * @rdy_queue:       List of V4L2 mem-to-mem queues
> >>>> + * @rdy_queue:       List of V4L2 mem-to-mem queues. If v4l2_m2m_buf_queue() is
> >>>> + *           called in struct vb2_ops->buf_queue(), the buffer enqueued
> >>>> + *           by user would be added to this list.
> >>>>     * @rdy_spinlock: spin lock to protect the struct usage
> >>>>     * @num_rdy: number of buffers ready to be processed
> >>>> + * @hw_queue:        A list for tracking the buffer is occupied by the hardware
> >>>> + *           (or device's firmware). A buffer could only be in either
> >>>> + *           this list or @rdy_queue.
> >>>> + *           Driver may choose not to use this list while uses its own
> >>>> + *           private data to do this work.
> >>>>     * @buffered:        is the queue buffered?
> >>>>     *
> >>>>     * Queue for buffers ready to be processed as soon as this
> >>>> @@ -68,6 +75,7 @@ struct v4l2_m2m_queue_ctx {
> >>>>         struct list_head        rdy_queue;
> >>>>         spinlock_t              rdy_spinlock;
> >>>>         u8                      num_rdy;
> >>>> +     struct list_head        hw_queue;
> >>>>         bool                    buffered;
> >>>>    };
> >>>>
> >>>> --
> >>>> 2.17.1
> >>>>
> >> --
> >> Hsia-Jun(Randy) Li
> >>
>
> --
> Hsia-Jun(Randy) Li

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH 2/2] media: v4l2-mem2mem: add a list for buf used by hw
  2023-07-27  7:43       ` Tomasz Figa
@ 2023-07-27 16:58         ` Nicolas Dufresne
  2023-07-28  4:43           ` Tomasz Figa
  0 siblings, 1 reply; 33+ messages in thread
From: Nicolas Dufresne @ 2023-07-27 16:58 UTC (permalink / raw)
  To: Tomasz Figa
  Cc: Hsia-Jun Li, linux-media, ayaka, hans.verkuil, mchehab,
	laurent.pinchart, hiroh, hverkuil, linux-kernel

Le jeudi 27 juillet 2023 à 16:43 +0900, Tomasz Figa a écrit :
> On Mon, Jul 17, 2023 at 11:07 PM Nicolas Dufresne <nicolas@ndufresne.ca> wrote:
> > 
> > Le mercredi 12 juillet 2023 à 09:33 +0000, Tomasz Figa a écrit :
> > > On Tue, Jul 04, 2023 at 12:00:38PM +0800, Hsia-Jun Li wrote:
> > > > From: "Hsia-Jun(Randy) Li" <randy.li@synaptics.com>
> > > > 
> > > > Many drivers have to create its own buf_struct for a
> > > > vb2_queue to track such a state. Also driver has to
> > > > iterate over rdy_queue every times to find out a buffer
> > > > which is not sent to hardware(or firmware), this new
> > > > list just offers the driver a place to store the buffer
> > > > that hardware(firmware) has acknowledged.
> > > > 
> > > > One important advance about this list, it doesn't like
> > > > rdy_queue which both bottom half of the user calling
> > > > could operate it, while the v4l2 worker would as well.
> > > > The v4l2 core could only operate this queue when its
> > > > v4l2_context is not running, the driver would only
> > > > access this new hw_queue in its own worker.
> > > 
> > > Could you describe in what case such a list would be useful for a
> > > mem2mem driver?
> > 
> > Today all driver must track buffers that are "owned by the hardware". This is a
> > concept dictated by the m2m framework and enforced through the ACTIVE flag. All
> > buffers from this list must be mark as done/error/queued after streamoff of the
> > respective queue in order to acknowledge that they are no longer in use by the
> > HW. Not doing so will warn:
> > 
> >   videobuf2_common: driver bug: stop_streaming operation is leaving buf ...
> > 
> > Though, there is no queue to easily iterate them. All driver endup having their
> > own queue, or just leaving the buffers in the rdy_queue (which isn't better).
> > 
> 
> Thanks for the explanation. I see how it could be useful now.
> 
> Although I guess this is a problem specifically for hardware (or
> firmware) which can internally queue more than 1 buffer, right?
> Otherwise the current buffer could just stay at the top of the
> rdy_queue until it's removed by the driver's completion handler,
> timeout/error handler or context destruction.

Correct, its only an issue when you need to process multiple src buffers before
producing a dst buffer. If affects stateful decoder, stateful encoders and
deinterlacer as far as I'm aware.

Nicolas

> 
> Best regards,
> Tomasz
> 
> > Nicolas
> > > 
> > > > 
> > > > Signed-off-by: Hsia-Jun(Randy) Li <randy.li@synaptics.com>
> > > > ---
> > > >  drivers/media/v4l2-core/v4l2-mem2mem.c | 25 +++++++++++++++++--------
> > > >  include/media/v4l2-mem2mem.h           | 10 +++++++++-
> > > >  2 files changed, 26 insertions(+), 9 deletions(-)
> > > > 
> > > > diff --git a/drivers/media/v4l2-core/v4l2-mem2mem.c b/drivers/media/v4l2-core/v4l2-mem2mem.c
> > > > index c771aba42015..b4151147d5bd 100644
> > > > --- a/drivers/media/v4l2-core/v4l2-mem2mem.c
> > > > +++ b/drivers/media/v4l2-core/v4l2-mem2mem.c
> > > > @@ -321,15 +321,21 @@ static void __v4l2_m2m_try_queue(struct v4l2_m2m_dev *m2m_dev,
> > > >             goto job_unlock;
> > > >     }
> > > > 
> > > > -   src = v4l2_m2m_next_src_buf(m2m_ctx);
> > > > -   dst = v4l2_m2m_next_dst_buf(m2m_ctx);
> > > > -   if (!src && !m2m_ctx->out_q_ctx.buffered) {
> > > > -           dprintk("No input buffers available\n");
> > > > -           goto job_unlock;
> > > > +   if (list_empty(&m2m_ctx->out_q_ctx.hw_queue)) {
> > > > +           src = v4l2_m2m_next_src_buf(m2m_ctx);
> > > > +
> > > > +           if (!src && !m2m_ctx->out_q_ctx.buffered) {
> > > > +                   dprintk("No input buffers available\n");
> > > > +                   goto job_unlock;
> > > > +           }
> > > >     }
> > > > -   if (!dst && !m2m_ctx->cap_q_ctx.buffered) {
> > > > -           dprintk("No output buffers available\n");
> > > > -           goto job_unlock;
> > > > +
> > > > +   if (list_empty(&m2m_ctx->cap_q_ctx.hw_queue)) {
> > > > +           dst = v4l2_m2m_next_dst_buf(m2m_ctx);
> > > > +           if (!dst && !m2m_ctx->cap_q_ctx.buffered) {
> > > > +                   dprintk("No output buffers available\n");
> > > > +                   goto job_unlock;
> > > > +           }
> > > >     }
> > > 
> > > src and dst would be referenced unitialized below if neither of the
> > > above ifs hits...
> > > 
> > > Best regards,
> > > Tomasz
> > > 
> > > > 
> > > >     m2m_ctx->new_frame = true;
> > > > @@ -896,6 +902,7 @@ int v4l2_m2m_streamoff(struct file *file, struct v4l2_m2m_ctx *m2m_ctx,
> > > >     INIT_LIST_HEAD(&q_ctx->rdy_queue);
> > > >     q_ctx->num_rdy = 0;
> > > >     spin_unlock_irqrestore(&q_ctx->rdy_spinlock, flags);
> > > > +   INIT_LIST_HEAD(&q_ctx->hw_queue);
> > > > 
> > > >     if (m2m_dev->curr_ctx == m2m_ctx) {
> > > >             m2m_dev->curr_ctx = NULL;
> > > > @@ -1234,6 +1241,8 @@ struct v4l2_m2m_ctx *v4l2_m2m_ctx_init(struct v4l2_m2m_dev *m2m_dev,
> > > > 
> > > >     INIT_LIST_HEAD(&out_q_ctx->rdy_queue);
> > > >     INIT_LIST_HEAD(&cap_q_ctx->rdy_queue);
> > > > +   INIT_LIST_HEAD(&out_q_ctx->hw_queue);
> > > > +   INIT_LIST_HEAD(&cap_q_ctx->hw_queue);
> > > >     spin_lock_init(&out_q_ctx->rdy_spinlock);
> > > >     spin_lock_init(&cap_q_ctx->rdy_spinlock);
> > > > 
> > > > diff --git a/include/media/v4l2-mem2mem.h b/include/media/v4l2-mem2mem.h
> > > > index d6c8eb2b5201..2342656e582d 100644
> > > > --- a/include/media/v4l2-mem2mem.h
> > > > +++ b/include/media/v4l2-mem2mem.h
> > > > @@ -53,9 +53,16 @@ struct v4l2_m2m_dev;
> > > >   * processed
> > > >   *
> > > >   * @q:             pointer to struct &vb2_queue
> > > > - * @rdy_queue:     List of V4L2 mem-to-mem queues
> > > > + * @rdy_queue:     List of V4L2 mem-to-mem queues. If v4l2_m2m_buf_queue() is
> > > > + *         called in struct vb2_ops->buf_queue(), the buffer enqueued
> > > > + *         by user would be added to this list.
> > > >   * @rdy_spinlock: spin lock to protect the struct usage
> > > >   * @num_rdy:       number of buffers ready to be processed
> > > > + * @hw_queue:      A list for tracking the buffer is occupied by the hardware
> > > > + *                 (or device's firmware). A buffer could only be in either
> > > > + *                 this list or @rdy_queue.
> > > > + *                 Driver may choose not to use this list while uses its own
> > > > + *                 private data to do this work.
> > > >   * @buffered:      is the queue buffered?
> > > >   *
> > > >   * Queue for buffers ready to be processed as soon as this
> > > > @@ -68,6 +75,7 @@ struct v4l2_m2m_queue_ctx {
> > > >     struct list_head        rdy_queue;
> > > >     spinlock_t              rdy_spinlock;
> > > >     u8                      num_rdy;
> > > > +   struct list_head        hw_queue;
> > > >     bool                    buffered;
> > > >  };
> > > > 
> > > > --
> > > > 2.17.1
> > > > 
> > 


^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH 2/2] media: v4l2-mem2mem: add a list for buf used by hw
  2023-07-27 16:58         ` Nicolas Dufresne
@ 2023-07-28  4:43           ` Tomasz Figa
  2023-07-28  7:08             ` Hsia-Jun Li
  2023-07-28 16:09             ` Nicolas Dufresne
  0 siblings, 2 replies; 33+ messages in thread
From: Tomasz Figa @ 2023-07-28  4:43 UTC (permalink / raw)
  To: Nicolas Dufresne, Hsia-Jun Li
  Cc: linux-media, ayaka, hans.verkuil, mchehab, laurent.pinchart,
	hiroh, hverkuil, linux-kernel

On Fri, Jul 28, 2023 at 1:58 AM Nicolas Dufresne <nicolas@ndufresne.ca> wrote:
>
> Le jeudi 27 juillet 2023 à 16:43 +0900, Tomasz Figa a écrit :
> > On Mon, Jul 17, 2023 at 11:07 PM Nicolas Dufresne <nicolas@ndufresne.ca> wrote:
> > >
> > > Le mercredi 12 juillet 2023 à 09:33 +0000, Tomasz Figa a écrit :
> > > > On Tue, Jul 04, 2023 at 12:00:38PM +0800, Hsia-Jun Li wrote:
> > > > > From: "Hsia-Jun(Randy) Li" <randy.li@synaptics.com>
> > > > >
> > > > > Many drivers have to create its own buf_struct for a
> > > > > vb2_queue to track such a state. Also driver has to
> > > > > iterate over rdy_queue every times to find out a buffer
> > > > > which is not sent to hardware(or firmware), this new
> > > > > list just offers the driver a place to store the buffer
> > > > > that hardware(firmware) has acknowledged.
> > > > >
> > > > > One important advance about this list, it doesn't like
> > > > > rdy_queue which both bottom half of the user calling
> > > > > could operate it, while the v4l2 worker would as well.
> > > > > The v4l2 core could only operate this queue when its
> > > > > v4l2_context is not running, the driver would only
> > > > > access this new hw_queue in its own worker.
> > > >
> > > > Could you describe in what case such a list would be useful for a
> > > > mem2mem driver?
> > >
> > > Today all driver must track buffers that are "owned by the hardware". This is a
> > > concept dictated by the m2m framework and enforced through the ACTIVE flag. All
> > > buffers from this list must be mark as done/error/queued after streamoff of the
> > > respective queue in order to acknowledge that they are no longer in use by the
> > > HW. Not doing so will warn:
> > >
> > >   videobuf2_common: driver bug: stop_streaming operation is leaving buf ...
> > >
> > > Though, there is no queue to easily iterate them. All driver endup having their
> > > own queue, or just leaving the buffers in the rdy_queue (which isn't better).
> > >
> >
> > Thanks for the explanation. I see how it could be useful now.
> >
> > Although I guess this is a problem specifically for hardware (or
> > firmware) which can internally queue more than 1 buffer, right?
> > Otherwise the current buffer could just stay at the top of the
> > rdy_queue until it's removed by the driver's completion handler,
> > timeout/error handler or context destruction.
>
> Correct, its only an issue when you need to process multiple src buffers before
> producing a dst buffer. If affects stateful decoder, stateful encoders and
> deinterlacer as far as I'm aware.

Is it actually necessary to keep those buffers in a list in that case, though?
I can see that a deinterlacer would indeed need 2 input buffers to
perform the deinterlacing operation, but those would be just known to
the driver, since it's running the task currently.
For a stateful decoder, wouldn't it just consume the bitstream buffer
(producing something partially decoded to its own internal buffers)
and return it shortly?
The most realistic scenario would be for stateful encoders which could
keep some input buffers as reference frames for further encoding, but
then would this patch actually work for them? It would make
__v4l2_m2m_try_queue never add the context to the job_queue if there
are some buffers in that hw_queue list.

Maybe what I need here are actual patches modifying some existing
drivers. Randy, would you be able to include that in the next version?
Thanks.

Best regards,
Tomasz

>
> Nicolas
>
> >
> > Best regards,
> > Tomasz
> >
> > > Nicolas
> > > >
> > > > >
> > > > > Signed-off-by: Hsia-Jun(Randy) Li <randy.li@synaptics.com>
> > > > > ---
> > > > >  drivers/media/v4l2-core/v4l2-mem2mem.c | 25 +++++++++++++++++--------
> > > > >  include/media/v4l2-mem2mem.h           | 10 +++++++++-
> > > > >  2 files changed, 26 insertions(+), 9 deletions(-)
> > > > >
> > > > > diff --git a/drivers/media/v4l2-core/v4l2-mem2mem.c b/drivers/media/v4l2-core/v4l2-mem2mem.c
> > > > > index c771aba42015..b4151147d5bd 100644
> > > > > --- a/drivers/media/v4l2-core/v4l2-mem2mem.c
> > > > > +++ b/drivers/media/v4l2-core/v4l2-mem2mem.c
> > > > > @@ -321,15 +321,21 @@ static void __v4l2_m2m_try_queue(struct v4l2_m2m_dev *m2m_dev,
> > > > >             goto job_unlock;
> > > > >     }
> > > > >
> > > > > -   src = v4l2_m2m_next_src_buf(m2m_ctx);
> > > > > -   dst = v4l2_m2m_next_dst_buf(m2m_ctx);
> > > > > -   if (!src && !m2m_ctx->out_q_ctx.buffered) {
> > > > > -           dprintk("No input buffers available\n");
> > > > > -           goto job_unlock;
> > > > > +   if (list_empty(&m2m_ctx->out_q_ctx.hw_queue)) {
> > > > > +           src = v4l2_m2m_next_src_buf(m2m_ctx);
> > > > > +
> > > > > +           if (!src && !m2m_ctx->out_q_ctx.buffered) {
> > > > > +                   dprintk("No input buffers available\n");
> > > > > +                   goto job_unlock;
> > > > > +           }
> > > > >     }
> > > > > -   if (!dst && !m2m_ctx->cap_q_ctx.buffered) {
> > > > > -           dprintk("No output buffers available\n");
> > > > > -           goto job_unlock;
> > > > > +
> > > > > +   if (list_empty(&m2m_ctx->cap_q_ctx.hw_queue)) {
> > > > > +           dst = v4l2_m2m_next_dst_buf(m2m_ctx);
> > > > > +           if (!dst && !m2m_ctx->cap_q_ctx.buffered) {
> > > > > +                   dprintk("No output buffers available\n");
> > > > > +                   goto job_unlock;
> > > > > +           }
> > > > >     }
> > > >
> > > > src and dst would be referenced unitialized below if neither of the
> > > > above ifs hits...
> > > >
> > > > Best regards,
> > > > Tomasz
> > > >
> > > > >
> > > > >     m2m_ctx->new_frame = true;
> > > > > @@ -896,6 +902,7 @@ int v4l2_m2m_streamoff(struct file *file, struct v4l2_m2m_ctx *m2m_ctx,
> > > > >     INIT_LIST_HEAD(&q_ctx->rdy_queue);
> > > > >     q_ctx->num_rdy = 0;
> > > > >     spin_unlock_irqrestore(&q_ctx->rdy_spinlock, flags);
> > > > > +   INIT_LIST_HEAD(&q_ctx->hw_queue);
> > > > >
> > > > >     if (m2m_dev->curr_ctx == m2m_ctx) {
> > > > >             m2m_dev->curr_ctx = NULL;
> > > > > @@ -1234,6 +1241,8 @@ struct v4l2_m2m_ctx *v4l2_m2m_ctx_init(struct v4l2_m2m_dev *m2m_dev,
> > > > >
> > > > >     INIT_LIST_HEAD(&out_q_ctx->rdy_queue);
> > > > >     INIT_LIST_HEAD(&cap_q_ctx->rdy_queue);
> > > > > +   INIT_LIST_HEAD(&out_q_ctx->hw_queue);
> > > > > +   INIT_LIST_HEAD(&cap_q_ctx->hw_queue);
> > > > >     spin_lock_init(&out_q_ctx->rdy_spinlock);
> > > > >     spin_lock_init(&cap_q_ctx->rdy_spinlock);
> > > > >
> > > > > diff --git a/include/media/v4l2-mem2mem.h b/include/media/v4l2-mem2mem.h
> > > > > index d6c8eb2b5201..2342656e582d 100644
> > > > > --- a/include/media/v4l2-mem2mem.h
> > > > > +++ b/include/media/v4l2-mem2mem.h
> > > > > @@ -53,9 +53,16 @@ struct v4l2_m2m_dev;
> > > > >   * processed
> > > > >   *
> > > > >   * @q:             pointer to struct &vb2_queue
> > > > > - * @rdy_queue:     List of V4L2 mem-to-mem queues
> > > > > + * @rdy_queue:     List of V4L2 mem-to-mem queues. If v4l2_m2m_buf_queue() is
> > > > > + *         called in struct vb2_ops->buf_queue(), the buffer enqueued
> > > > > + *         by user would be added to this list.
> > > > >   * @rdy_spinlock: spin lock to protect the struct usage
> > > > >   * @num_rdy:       number of buffers ready to be processed
> > > > > + * @hw_queue:      A list for tracking the buffer is occupied by the hardware
> > > > > + *                 (or device's firmware). A buffer could only be in either
> > > > > + *                 this list or @rdy_queue.
> > > > > + *                 Driver may choose not to use this list while uses its own
> > > > > + *                 private data to do this work.
> > > > >   * @buffered:      is the queue buffered?
> > > > >   *
> > > > >   * Queue for buffers ready to be processed as soon as this
> > > > > @@ -68,6 +75,7 @@ struct v4l2_m2m_queue_ctx {
> > > > >     struct list_head        rdy_queue;
> > > > >     spinlock_t              rdy_spinlock;
> > > > >     u8                      num_rdy;
> > > > > +   struct list_head        hw_queue;
> > > > >     bool                    buffered;
> > > > >  };
> > > > >
> > > > > --
> > > > > 2.17.1
> > > > >
> > >
>

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH 2/2] media: v4l2-mem2mem: add a list for buf used by hw
  2023-07-28  4:43           ` Tomasz Figa
@ 2023-07-28  7:08             ` Hsia-Jun Li
  2023-07-28  7:26               ` Tomasz Figa
  2023-07-28 16:09             ` Nicolas Dufresne
  1 sibling, 1 reply; 33+ messages in thread
From: Hsia-Jun Li @ 2023-07-28  7:08 UTC (permalink / raw)
  To: Tomasz Figa
  Cc: Nicolas Dufresne, linux-media, ayaka, hans.verkuil, mchehab,
	laurent.pinchart, hiroh, hverkuil, linux-kernel



On 7/28/23 12:43, Tomasz Figa wrote:
> CAUTION: Email originated externally, do not click links or open attachments unless you recognize the sender and know the content is safe.
> 
> 
> On Fri, Jul 28, 2023 at 1:58 AM Nicolas Dufresne <nicolas@ndufresne.ca> wrote:
>>
>> Le jeudi 27 juillet 2023 à 16:43 +0900, Tomasz Figa a écrit :
>>> On Mon, Jul 17, 2023 at 11:07 PM Nicolas Dufresne <nicolas@ndufresne.ca> wrote:
>>>>
>>>> Le mercredi 12 juillet 2023 à 09:33 +0000, Tomasz Figa a écrit :
>>>>> On Tue, Jul 04, 2023 at 12:00:38PM +0800, Hsia-Jun Li wrote:
>>>>>> From: "Hsia-Jun(Randy) Li" <randy.li@synaptics.com>
>>>>>>
>>>>>> Many drivers have to create its own buf_struct for a
>>>>>> vb2_queue to track such a state. Also driver has to
>>>>>> iterate over rdy_queue every times to find out a buffer
>>>>>> which is not sent to hardware(or firmware), this new
>>>>>> list just offers the driver a place to store the buffer
>>>>>> that hardware(firmware) has acknowledged.
>>>>>>
>>>>>> One important advance about this list, it doesn't like
>>>>>> rdy_queue which both bottom half of the user calling
>>>>>> could operate it, while the v4l2 worker would as well.
>>>>>> The v4l2 core could only operate this queue when its
>>>>>> v4l2_context is not running, the driver would only
>>>>>> access this new hw_queue in its own worker.
>>>>>
>>>>> Could you describe in what case such a list would be useful for a
>>>>> mem2mem driver?
>>>>
>>>> Today all driver must track buffers that are "owned by the hardware". This is a
>>>> concept dictated by the m2m framework and enforced through the ACTIVE flag. All
>>>> buffers from this list must be mark as done/error/queued after streamoff of the
>>>> respective queue in order to acknowledge that they are no longer in use by the
>>>> HW. Not doing so will warn:
>>>>
>>>>    videobuf2_common: driver bug: stop_streaming operation is leaving buf ...
>>>>
>>>> Though, there is no queue to easily iterate them. All driver endup having their
>>>> own queue, or just leaving the buffers in the rdy_queue (which isn't better).
>>>>
>>>
>>> Thanks for the explanation. I see how it could be useful now.
>>>
>>> Although I guess this is a problem specifically for hardware (or
>>> firmware) which can internally queue more than 1 buffer, right?
>>> Otherwise the current buffer could just stay at the top of the
>>> rdy_queue until it's removed by the driver's completion handler,
>>> timeout/error handler or context destruction.
>>
>> Correct, its only an issue when you need to process multiple src buffers before
>> producing a dst buffer. If affects stateful decoder, stateful encoders and
>> deinterlacer as far as I'm aware.
> 
> Is it actually necessary to keep those buffers in a list in that case, though?
> I can see that a deinterlacer would indeed need 2 input buffers to
> perform the deinterlacing operation, but those would be just known to
> the driver, since it's running the task currently.
> For a stateful decoder, wouldn't it just consume the bitstream buffer
> (producing something partially decoded to its own internal buffers)
> and return it shortly?
Display re-order. Firmware could do such batch work, taking a few 
bitstream buffer, then output a list graphics buffer in the display 
order also discard the usage of the non-display buffer when it is 
removed from dpb.

Even in one input and one output mode, firmware need to do redo, let the 
driver know when a graphics buffer could be display, so firmware would 
usually hold the graphics buffer(frame) until its display time.

Besides, I hate the driver occupied a large of memory without user's 
order. I would like to drop those internal buffers.
> The most realistic scenario would be for stateful encoders which could
> keep some input buffers as reference frames for further encoding, but
> then would this patch actually work for them? It would make
> __v4l2_m2m_try_queue never add the context to the job_queue if there
> are some buffers in that hw_queue list.
why?
> 
> Maybe what I need here are actual patches modifying some existing
> drivers. Randy, would you be able to include that in the next version?
May not. The Synaptics VideoSmart is a secure video platform(DRM), I 
could release a snapshot of the driver when I got the permission, that 
would be after the official release of the SDK.
But you may not be able to compile it because we have our own TEE 
interface(not optee), also running it because the trusted app would be 
signed with a per-device key.
> Thanks.
> 
> Best regards,
> Tomasz
> 
>>
>> Nicolas
>>
>>>
>>> Best regards,
>>> Tomasz
>>>
>>>> Nicolas
>>>>>
>>>>>>
>>>>>> Signed-off-by: Hsia-Jun(Randy) Li <randy.li@synaptics.com>
>>>>>> ---
>>>>>>   drivers/media/v4l2-core/v4l2-mem2mem.c | 25 +++++++++++++++++--------
>>>>>>   include/media/v4l2-mem2mem.h           | 10 +++++++++-
>>>>>>   2 files changed, 26 insertions(+), 9 deletions(-)
>>>>>>
>>>>>> diff --git a/drivers/media/v4l2-core/v4l2-mem2mem.c b/drivers/media/v4l2-core/v4l2-mem2mem.c
>>>>>> index c771aba42015..b4151147d5bd 100644
>>>>>> --- a/drivers/media/v4l2-core/v4l2-mem2mem.c
>>>>>> +++ b/drivers/media/v4l2-core/v4l2-mem2mem.c
>>>>>> @@ -321,15 +321,21 @@ static void __v4l2_m2m_try_queue(struct v4l2_m2m_dev *m2m_dev,
>>>>>>              goto job_unlock;
>>>>>>      }
>>>>>>
>>>>>> -   src = v4l2_m2m_next_src_buf(m2m_ctx);
>>>>>> -   dst = v4l2_m2m_next_dst_buf(m2m_ctx);
>>>>>> -   if (!src && !m2m_ctx->out_q_ctx.buffered) {
>>>>>> -           dprintk("No input buffers available\n");
>>>>>> -           goto job_unlock;
>>>>>> +   if (list_empty(&m2m_ctx->out_q_ctx.hw_queue)) {
>>>>>> +           src = v4l2_m2m_next_src_buf(m2m_ctx);
>>>>>> +
>>>>>> +           if (!src && !m2m_ctx->out_q_ctx.buffered) {
>>>>>> +                   dprintk("No input buffers available\n");
>>>>>> +                   goto job_unlock;
>>>>>> +           }
>>>>>>      }
>>>>>> -   if (!dst && !m2m_ctx->cap_q_ctx.buffered) {
>>>>>> -           dprintk("No output buffers available\n");
>>>>>> -           goto job_unlock;
>>>>>> +
>>>>>> +   if (list_empty(&m2m_ctx->cap_q_ctx.hw_queue)) {
>>>>>> +           dst = v4l2_m2m_next_dst_buf(m2m_ctx);
>>>>>> +           if (!dst && !m2m_ctx->cap_q_ctx.buffered) {
>>>>>> +                   dprintk("No output buffers available\n");
>>>>>> +                   goto job_unlock;
>>>>>> +           }
>>>>>>      }
>>>>>
>>>>> src and dst would be referenced unitialized below if neither of the
>>>>> above ifs hits...
>>>>>
>>>>> Best regards,
>>>>> Tomasz
>>>>>
>>>>>>
>>>>>>      m2m_ctx->new_frame = true;
>>>>>> @@ -896,6 +902,7 @@ int v4l2_m2m_streamoff(struct file *file, struct v4l2_m2m_ctx *m2m_ctx,
>>>>>>      INIT_LIST_HEAD(&q_ctx->rdy_queue);
>>>>>>      q_ctx->num_rdy = 0;
>>>>>>      spin_unlock_irqrestore(&q_ctx->rdy_spinlock, flags);
>>>>>> +   INIT_LIST_HEAD(&q_ctx->hw_queue);
>>>>>>
>>>>>>      if (m2m_dev->curr_ctx == m2m_ctx) {
>>>>>>              m2m_dev->curr_ctx = NULL;
>>>>>> @@ -1234,6 +1241,8 @@ struct v4l2_m2m_ctx *v4l2_m2m_ctx_init(struct v4l2_m2m_dev *m2m_dev,
>>>>>>
>>>>>>      INIT_LIST_HEAD(&out_q_ctx->rdy_queue);
>>>>>>      INIT_LIST_HEAD(&cap_q_ctx->rdy_queue);
>>>>>> +   INIT_LIST_HEAD(&out_q_ctx->hw_queue);
>>>>>> +   INIT_LIST_HEAD(&cap_q_ctx->hw_queue);
>>>>>>      spin_lock_init(&out_q_ctx->rdy_spinlock);
>>>>>>      spin_lock_init(&cap_q_ctx->rdy_spinlock);
>>>>>>
>>>>>> diff --git a/include/media/v4l2-mem2mem.h b/include/media/v4l2-mem2mem.h
>>>>>> index d6c8eb2b5201..2342656e582d 100644
>>>>>> --- a/include/media/v4l2-mem2mem.h
>>>>>> +++ b/include/media/v4l2-mem2mem.h
>>>>>> @@ -53,9 +53,16 @@ struct v4l2_m2m_dev;
>>>>>>    * processed
>>>>>>    *
>>>>>>    * @q:             pointer to struct &vb2_queue
>>>>>> - * @rdy_queue:     List of V4L2 mem-to-mem queues
>>>>>> + * @rdy_queue:     List of V4L2 mem-to-mem queues. If v4l2_m2m_buf_queue() is
>>>>>> + *         called in struct vb2_ops->buf_queue(), the buffer enqueued
>>>>>> + *         by user would be added to this list.
>>>>>>    * @rdy_spinlock: spin lock to protect the struct usage
>>>>>>    * @num_rdy:       number of buffers ready to be processed
>>>>>> + * @hw_queue:      A list for tracking the buffer is occupied by the hardware
>>>>>> + *                 (or device's firmware). A buffer could only be in either
>>>>>> + *                 this list or @rdy_queue.
>>>>>> + *                 Driver may choose not to use this list while uses its own
>>>>>> + *                 private data to do this work.
>>>>>>    * @buffered:      is the queue buffered?
>>>>>>    *
>>>>>>    * Queue for buffers ready to be processed as soon as this
>>>>>> @@ -68,6 +75,7 @@ struct v4l2_m2m_queue_ctx {
>>>>>>      struct list_head        rdy_queue;
>>>>>>      spinlock_t              rdy_spinlock;
>>>>>>      u8                      num_rdy;
>>>>>> +   struct list_head        hw_queue;
>>>>>>      bool                    buffered;
>>>>>>   };
>>>>>>
>>>>>> --
>>>>>> 2.17.1
>>>>>>
>>>>
>>

-- 
Hsia-Jun(Randy) Li

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH 2/2] media: v4l2-mem2mem: add a list for buf used by hw
  2023-07-28  7:08             ` Hsia-Jun Li
@ 2023-07-28  7:26               ` Tomasz Figa
  2023-07-28  7:37                 ` Hsia-Jun Li
  0 siblings, 1 reply; 33+ messages in thread
From: Tomasz Figa @ 2023-07-28  7:26 UTC (permalink / raw)
  To: Hsia-Jun Li
  Cc: Nicolas Dufresne, linux-media, ayaka, hans.verkuil, mchehab,
	laurent.pinchart, hiroh, hverkuil, linux-kernel

On Fri, Jul 28, 2023 at 4:09 PM Hsia-Jun Li <Randy.Li@synaptics.com> wrote:
>
>
>
> On 7/28/23 12:43, Tomasz Figa wrote:
> > CAUTION: Email originated externally, do not click links or open attachments unless you recognize the sender and know the content is safe.
> >
> >
> > On Fri, Jul 28, 2023 at 1:58 AM Nicolas Dufresne <nicolas@ndufresne.ca> wrote:
> >>
> >> Le jeudi 27 juillet 2023 à 16:43 +0900, Tomasz Figa a écrit :
> >>> On Mon, Jul 17, 2023 at 11:07 PM Nicolas Dufresne <nicolas@ndufresne.ca> wrote:
> >>>>
> >>>> Le mercredi 12 juillet 2023 à 09:33 +0000, Tomasz Figa a écrit :
> >>>>> On Tue, Jul 04, 2023 at 12:00:38PM +0800, Hsia-Jun Li wrote:
> >>>>>> From: "Hsia-Jun(Randy) Li" <randy.li@synaptics.com>
> >>>>>>
> >>>>>> Many drivers have to create its own buf_struct for a
> >>>>>> vb2_queue to track such a state. Also driver has to
> >>>>>> iterate over rdy_queue every times to find out a buffer
> >>>>>> which is not sent to hardware(or firmware), this new
> >>>>>> list just offers the driver a place to store the buffer
> >>>>>> that hardware(firmware) has acknowledged.
> >>>>>>
> >>>>>> One important advance about this list, it doesn't like
> >>>>>> rdy_queue which both bottom half of the user calling
> >>>>>> could operate it, while the v4l2 worker would as well.
> >>>>>> The v4l2 core could only operate this queue when its
> >>>>>> v4l2_context is not running, the driver would only
> >>>>>> access this new hw_queue in its own worker.
> >>>>>
> >>>>> Could you describe in what case such a list would be useful for a
> >>>>> mem2mem driver?
> >>>>
> >>>> Today all driver must track buffers that are "owned by the hardware". This is a
> >>>> concept dictated by the m2m framework and enforced through the ACTIVE flag. All
> >>>> buffers from this list must be mark as done/error/queued after streamoff of the
> >>>> respective queue in order to acknowledge that they are no longer in use by the
> >>>> HW. Not doing so will warn:
> >>>>
> >>>>    videobuf2_common: driver bug: stop_streaming operation is leaving buf ...
> >>>>
> >>>> Though, there is no queue to easily iterate them. All driver endup having their
> >>>> own queue, or just leaving the buffers in the rdy_queue (which isn't better).
> >>>>
> >>>
> >>> Thanks for the explanation. I see how it could be useful now.
> >>>
> >>> Although I guess this is a problem specifically for hardware (or
> >>> firmware) which can internally queue more than 1 buffer, right?
> >>> Otherwise the current buffer could just stay at the top of the
> >>> rdy_queue until it's removed by the driver's completion handler,
> >>> timeout/error handler or context destruction.
> >>
> >> Correct, its only an issue when you need to process multiple src buffers before
> >> producing a dst buffer. If affects stateful decoder, stateful encoders and
> >> deinterlacer as far as I'm aware.
> >
> > Is it actually necessary to keep those buffers in a list in that case, though?
> > I can see that a deinterlacer would indeed need 2 input buffers to
> > perform the deinterlacing operation, but those would be just known to
> > the driver, since it's running the task currently.
> > For a stateful decoder, wouldn't it just consume the bitstream buffer
> > (producing something partially decoded to its own internal buffers)
> > and return it shortly?
> Display re-order. Firmware could do such batch work, taking a few
> bitstream buffer, then output a list graphics buffer in the display
> order also discard the usage of the non-display buffer when it is
> removed from dpb.
>
> Even in one input and one output mode, firmware need to do redo, let the
> driver know when a graphics buffer could be display, so firmware would
> usually hold the graphics buffer(frame) until its display time.
>

Okay, so that hold would be for frame buffers, not bitstream buffers, right?
But yeah, I see that then it could hold onto those buffers until it's
their turn to display and it could be a bigger number of frames,
depending on the complexity of the codec.

> Besides, I hate the driver occupied a large of memory without user's
> order. I would like to drop those internal buffers.

I think this is one reason to migrate to the stateless decoder design.

> > The most realistic scenario would be for stateful encoders which could
> > keep some input buffers as reference frames for further encoding, but
> > then would this patch actually work for them? It would make
> > __v4l2_m2m_try_queue never add the context to the job_queue if there
> > are some buffers in that hw_queue list.
> why?
> >
> > Maybe what I need here are actual patches modifying some existing
> > drivers. Randy, would you be able to include that in the next version?
> May not. The Synaptics VideoSmart is a secure video platform(DRM), I
> could release a snapshot of the driver when I got the permission, that
> would be after the official release of the SDK.
> But you may not be able to compile it because we have our own TEE
> interface(not optee), also running it because the trusted app would be
> signed with a per-device key.

Could you modify another, already existing driver then?

> > Thanks.
> >
> > Best regards,
> > Tomasz
> >
> >>
> >> Nicolas
> >>
> >>>
> >>> Best regards,
> >>> Tomasz
> >>>
> >>>> Nicolas
> >>>>>
> >>>>>>
> >>>>>> Signed-off-by: Hsia-Jun(Randy) Li <randy.li@synaptics.com>
> >>>>>> ---
> >>>>>>   drivers/media/v4l2-core/v4l2-mem2mem.c | 25 +++++++++++++++++--------
> >>>>>>   include/media/v4l2-mem2mem.h           | 10 +++++++++-
> >>>>>>   2 files changed, 26 insertions(+), 9 deletions(-)
> >>>>>>
> >>>>>> diff --git a/drivers/media/v4l2-core/v4l2-mem2mem.c b/drivers/media/v4l2-core/v4l2-mem2mem.c
> >>>>>> index c771aba42015..b4151147d5bd 100644
> >>>>>> --- a/drivers/media/v4l2-core/v4l2-mem2mem.c
> >>>>>> +++ b/drivers/media/v4l2-core/v4l2-mem2mem.c
> >>>>>> @@ -321,15 +321,21 @@ static void __v4l2_m2m_try_queue(struct v4l2_m2m_dev *m2m_dev,
> >>>>>>              goto job_unlock;
> >>>>>>      }
> >>>>>>
> >>>>>> -   src = v4l2_m2m_next_src_buf(m2m_ctx);
> >>>>>> -   dst = v4l2_m2m_next_dst_buf(m2m_ctx);
> >>>>>> -   if (!src && !m2m_ctx->out_q_ctx.buffered) {
> >>>>>> -           dprintk("No input buffers available\n");
> >>>>>> -           goto job_unlock;
> >>>>>> +   if (list_empty(&m2m_ctx->out_q_ctx.hw_queue)) {
> >>>>>> +           src = v4l2_m2m_next_src_buf(m2m_ctx);
> >>>>>> +
> >>>>>> +           if (!src && !m2m_ctx->out_q_ctx.buffered) {
> >>>>>> +                   dprintk("No input buffers available\n");
> >>>>>> +                   goto job_unlock;
> >>>>>> +           }
> >>>>>>      }
> >>>>>> -   if (!dst && !m2m_ctx->cap_q_ctx.buffered) {
> >>>>>> -           dprintk("No output buffers available\n");
> >>>>>> -           goto job_unlock;
> >>>>>> +
> >>>>>> +   if (list_empty(&m2m_ctx->cap_q_ctx.hw_queue)) {
> >>>>>> +           dst = v4l2_m2m_next_dst_buf(m2m_ctx);
> >>>>>> +           if (!dst && !m2m_ctx->cap_q_ctx.buffered) {
> >>>>>> +                   dprintk("No output buffers available\n");
> >>>>>> +                   goto job_unlock;
> >>>>>> +           }
> >>>>>>      }
> >>>>>
> >>>>> src and dst would be referenced unitialized below if neither of the
> >>>>> above ifs hits...
> >>>>>
> >>>>> Best regards,
> >>>>> Tomasz
> >>>>>
> >>>>>>
> >>>>>>      m2m_ctx->new_frame = true;
> >>>>>> @@ -896,6 +902,7 @@ int v4l2_m2m_streamoff(struct file *file, struct v4l2_m2m_ctx *m2m_ctx,
> >>>>>>      INIT_LIST_HEAD(&q_ctx->rdy_queue);
> >>>>>>      q_ctx->num_rdy = 0;
> >>>>>>      spin_unlock_irqrestore(&q_ctx->rdy_spinlock, flags);
> >>>>>> +   INIT_LIST_HEAD(&q_ctx->hw_queue);
> >>>>>>
> >>>>>>      if (m2m_dev->curr_ctx == m2m_ctx) {
> >>>>>>              m2m_dev->curr_ctx = NULL;
> >>>>>> @@ -1234,6 +1241,8 @@ struct v4l2_m2m_ctx *v4l2_m2m_ctx_init(struct v4l2_m2m_dev *m2m_dev,
> >>>>>>
> >>>>>>      INIT_LIST_HEAD(&out_q_ctx->rdy_queue);
> >>>>>>      INIT_LIST_HEAD(&cap_q_ctx->rdy_queue);
> >>>>>> +   INIT_LIST_HEAD(&out_q_ctx->hw_queue);
> >>>>>> +   INIT_LIST_HEAD(&cap_q_ctx->hw_queue);
> >>>>>>      spin_lock_init(&out_q_ctx->rdy_spinlock);
> >>>>>>      spin_lock_init(&cap_q_ctx->rdy_spinlock);
> >>>>>>
> >>>>>> diff --git a/include/media/v4l2-mem2mem.h b/include/media/v4l2-mem2mem.h
> >>>>>> index d6c8eb2b5201..2342656e582d 100644
> >>>>>> --- a/include/media/v4l2-mem2mem.h
> >>>>>> +++ b/include/media/v4l2-mem2mem.h
> >>>>>> @@ -53,9 +53,16 @@ struct v4l2_m2m_dev;
> >>>>>>    * processed
> >>>>>>    *
> >>>>>>    * @q:             pointer to struct &vb2_queue
> >>>>>> - * @rdy_queue:     List of V4L2 mem-to-mem queues
> >>>>>> + * @rdy_queue:     List of V4L2 mem-to-mem queues. If v4l2_m2m_buf_queue() is
> >>>>>> + *         called in struct vb2_ops->buf_queue(), the buffer enqueued
> >>>>>> + *         by user would be added to this list.
> >>>>>>    * @rdy_spinlock: spin lock to protect the struct usage
> >>>>>>    * @num_rdy:       number of buffers ready to be processed
> >>>>>> + * @hw_queue:      A list for tracking the buffer is occupied by the hardware
> >>>>>> + *                 (or device's firmware). A buffer could only be in either
> >>>>>> + *                 this list or @rdy_queue.
> >>>>>> + *                 Driver may choose not to use this list while uses its own
> >>>>>> + *                 private data to do this work.
> >>>>>>    * @buffered:      is the queue buffered?
> >>>>>>    *
> >>>>>>    * Queue for buffers ready to be processed as soon as this
> >>>>>> @@ -68,6 +75,7 @@ struct v4l2_m2m_queue_ctx {
> >>>>>>      struct list_head        rdy_queue;
> >>>>>>      spinlock_t              rdy_spinlock;
> >>>>>>      u8                      num_rdy;
> >>>>>> +   struct list_head        hw_queue;
> >>>>>>      bool                    buffered;
> >>>>>>   };
> >>>>>>
> >>>>>> --
> >>>>>> 2.17.1
> >>>>>>
> >>>>
> >>
>
> --
> Hsia-Jun(Randy) Li

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH 2/2] media: v4l2-mem2mem: add a list for buf used by hw
  2023-07-28  7:26               ` Tomasz Figa
@ 2023-07-28  7:37                 ` Hsia-Jun Li
  2023-07-28 16:19                   ` Nicolas Dufresne
  0 siblings, 1 reply; 33+ messages in thread
From: Hsia-Jun Li @ 2023-07-28  7:37 UTC (permalink / raw)
  To: Tomasz Figa
  Cc: Nicolas Dufresne, linux-media, ayaka, hans.verkuil, mchehab,
	laurent.pinchart, hiroh, hverkuil, linux-kernel



On 7/28/23 15:26, Tomasz Figa wrote:
> CAUTION: Email originated externally, do not click links or open attachments unless you recognize the sender and know the content is safe.
> 
> 
> On Fri, Jul 28, 2023 at 4:09 PM Hsia-Jun Li <Randy.Li@synaptics.com> wrote:
>>
>>
>>
>> On 7/28/23 12:43, Tomasz Figa wrote:
>>> CAUTION: Email originated externally, do not click links or open attachments unless you recognize the sender and know the content is safe.
>>>
>>>
>>> On Fri, Jul 28, 2023 at 1:58 AM Nicolas Dufresne <nicolas@ndufresne.ca> wrote:
>>>>
>>>> Le jeudi 27 juillet 2023 à 16:43 +0900, Tomasz Figa a écrit :
>>>>> On Mon, Jul 17, 2023 at 11:07 PM Nicolas Dufresne <nicolas@ndufresne.ca> wrote:
>>>>>>
>>>>>> Le mercredi 12 juillet 2023 à 09:33 +0000, Tomasz Figa a écrit :
>>>>>>> On Tue, Jul 04, 2023 at 12:00:38PM +0800, Hsia-Jun Li wrote:
>>>>>>>> From: "Hsia-Jun(Randy) Li" <randy.li@synaptics.com>
>>>>>>>>
>>>>>>>> Many drivers have to create its own buf_struct for a
>>>>>>>> vb2_queue to track such a state. Also driver has to
>>>>>>>> iterate over rdy_queue every times to find out a buffer
>>>>>>>> which is not sent to hardware(or firmware), this new
>>>>>>>> list just offers the driver a place to store the buffer
>>>>>>>> that hardware(firmware) has acknowledged.
>>>>>>>>
>>>>>>>> One important advance about this list, it doesn't like
>>>>>>>> rdy_queue which both bottom half of the user calling
>>>>>>>> could operate it, while the v4l2 worker would as well.
>>>>>>>> The v4l2 core could only operate this queue when its
>>>>>>>> v4l2_context is not running, the driver would only
>>>>>>>> access this new hw_queue in its own worker.
>>>>>>>
>>>>>>> Could you describe in what case such a list would be useful for a
>>>>>>> mem2mem driver?
>>>>>>
>>>>>> Today all driver must track buffers that are "owned by the hardware". This is a
>>>>>> concept dictated by the m2m framework and enforced through the ACTIVE flag. All
>>>>>> buffers from this list must be mark as done/error/queued after streamoff of the
>>>>>> respective queue in order to acknowledge that they are no longer in use by the
>>>>>> HW. Not doing so will warn:
>>>>>>
>>>>>>     videobuf2_common: driver bug: stop_streaming operation is leaving buf ...
>>>>>>
>>>>>> Though, there is no queue to easily iterate them. All driver endup having their
>>>>>> own queue, or just leaving the buffers in the rdy_queue (which isn't better).
>>>>>>
>>>>>
>>>>> Thanks for the explanation. I see how it could be useful now.
>>>>>
>>>>> Although I guess this is a problem specifically for hardware (or
>>>>> firmware) which can internally queue more than 1 buffer, right?
>>>>> Otherwise the current buffer could just stay at the top of the
>>>>> rdy_queue until it's removed by the driver's completion handler,
>>>>> timeout/error handler or context destruction.
>>>>
>>>> Correct, its only an issue when you need to process multiple src buffers before
>>>> producing a dst buffer. If affects stateful decoder, stateful encoders and
>>>> deinterlacer as far as I'm aware.
>>>
>>> Is it actually necessary to keep those buffers in a list in that case, though?
>>> I can see that a deinterlacer would indeed need 2 input buffers to
>>> perform the deinterlacing operation, but those would be just known to
>>> the driver, since it's running the task currently.
>>> For a stateful decoder, wouldn't it just consume the bitstream buffer
>>> (producing something partially decoded to its own internal buffers)
>>> and return it shortly?
>> Display re-order. Firmware could do such batch work, taking a few
>> bitstream buffer, then output a list graphics buffer in the display
>> order also discard the usage of the non-display buffer when it is
>> removed from dpb.
>>
>> Even in one input and one output mode, firmware need to do redo, let the
>> driver know when a graphics buffer could be display, so firmware would
>> usually hold the graphics buffer(frame) until its display time.
>>
> 
> Okay, so that hold would be for frame buffers, not bitstream buffers, right?
For the 1:1 model, decoder won't hold the input(OUTPUT queue) buffer 
usually.
While for the VP9, we have a super frame and temporal unit packing for 
AV1 which break the current API requirement for an AU in a buffer. The 
hardware would trigger multiple work for that(that means multiple irqs 
ack for a usual devices).
For the encoder, it is a different story.
> But yeah, I see that then it could hold onto those buffers until it's
> their turn to display and it could be a bigger number of frames,
> depending on the complexity of the codec.
> 
>> Besides, I hate the driver occupied a large of memory without user's
>> order. I would like to drop those internal buffers.
> 
> I think this is one reason to migrate to the stateless decoder design.
> 
I didn't know such plan here. I don't think the current stateless API 
could export the reconstruction buffers for encoder or post-processing 
buffer for decoder to us.
>>> The most realistic scenario would be for stateful encoders which could
>>> keep some input buffers as reference frames for further encoding, but
>>> then would this patch actually work for them? It would make
>>> __v4l2_m2m_try_queue never add the context to the job_queue if there
>>> are some buffers in that hw_queue list.
>> why?
>>>
>>> Maybe what I need here are actual patches modifying some existing
>>> drivers. Randy, would you be able to include that in the next version?
>> May not. The Synaptics VideoSmart is a secure video platform(DRM), I
>> could release a snapshot of the driver when I got the permission, that
>> would be after the official release of the SDK.
>> But you may not be able to compile it because we have our own TEE
>> interface(not optee), also running it because the trusted app would be
>> signed with a per-device key.
> 
> Could you modify another, already existing driver then?
> 
>>> Thanks.
>>>
>>> Best regards,
>>> Tomasz
>>>
>>>>
>>>> Nicolas
>>>>
>>>>>
>>>>> Best regards,
>>>>> Tomasz
>>>>>
>>>>>> Nicolas
>>>>>>>
>>>>>>>>
>>>>>>>> Signed-off-by: Hsia-Jun(Randy) Li <randy.li@synaptics.com>
>>>>>>>> ---
>>>>>>>>    drivers/media/v4l2-core/v4l2-mem2mem.c | 25 +++++++++++++++++--------
>>>>>>>>    include/media/v4l2-mem2mem.h           | 10 +++++++++-
>>>>>>>>    2 files changed, 26 insertions(+), 9 deletions(-)
>>>>>>>>
>>>>>>>> diff --git a/drivers/media/v4l2-core/v4l2-mem2mem.c b/drivers/media/v4l2-core/v4l2-mem2mem.c
>>>>>>>> index c771aba42015..b4151147d5bd 100644
>>>>>>>> --- a/drivers/media/v4l2-core/v4l2-mem2mem.c
>>>>>>>> +++ b/drivers/media/v4l2-core/v4l2-mem2mem.c
>>>>>>>> @@ -321,15 +321,21 @@ static void __v4l2_m2m_try_queue(struct v4l2_m2m_dev *m2m_dev,
>>>>>>>>               goto job_unlock;
>>>>>>>>       }
>>>>>>>>
>>>>>>>> -   src = v4l2_m2m_next_src_buf(m2m_ctx);
>>>>>>>> -   dst = v4l2_m2m_next_dst_buf(m2m_ctx);
>>>>>>>> -   if (!src && !m2m_ctx->out_q_ctx.buffered) {
>>>>>>>> -           dprintk("No input buffers available\n");
>>>>>>>> -           goto job_unlock;
>>>>>>>> +   if (list_empty(&m2m_ctx->out_q_ctx.hw_queue)) {
>>>>>>>> +           src = v4l2_m2m_next_src_buf(m2m_ctx);
>>>>>>>> +
>>>>>>>> +           if (!src && !m2m_ctx->out_q_ctx.buffered) {
>>>>>>>> +                   dprintk("No input buffers available\n");
>>>>>>>> +                   goto job_unlock;
>>>>>>>> +           }
>>>>>>>>       }
>>>>>>>> -   if (!dst && !m2m_ctx->cap_q_ctx.buffered) {
>>>>>>>> -           dprintk("No output buffers available\n");
>>>>>>>> -           goto job_unlock;
>>>>>>>> +
>>>>>>>> +   if (list_empty(&m2m_ctx->cap_q_ctx.hw_queue)) {
>>>>>>>> +           dst = v4l2_m2m_next_dst_buf(m2m_ctx);
>>>>>>>> +           if (!dst && !m2m_ctx->cap_q_ctx.buffered) {
>>>>>>>> +                   dprintk("No output buffers available\n");
>>>>>>>> +                   goto job_unlock;
>>>>>>>> +           }
>>>>>>>>       }
>>>>>>>
>>>>>>> src and dst would be referenced unitialized below if neither of the
>>>>>>> above ifs hits...
>>>>>>>
>>>>>>> Best regards,
>>>>>>> Tomasz
>>>>>>>
>>>>>>>>
>>>>>>>>       m2m_ctx->new_frame = true;
>>>>>>>> @@ -896,6 +902,7 @@ int v4l2_m2m_streamoff(struct file *file, struct v4l2_m2m_ctx *m2m_ctx,
>>>>>>>>       INIT_LIST_HEAD(&q_ctx->rdy_queue);
>>>>>>>>       q_ctx->num_rdy = 0;
>>>>>>>>       spin_unlock_irqrestore(&q_ctx->rdy_spinlock, flags);
>>>>>>>> +   INIT_LIST_HEAD(&q_ctx->hw_queue);
>>>>>>>>
>>>>>>>>       if (m2m_dev->curr_ctx == m2m_ctx) {
>>>>>>>>               m2m_dev->curr_ctx = NULL;
>>>>>>>> @@ -1234,6 +1241,8 @@ struct v4l2_m2m_ctx *v4l2_m2m_ctx_init(struct v4l2_m2m_dev *m2m_dev,
>>>>>>>>
>>>>>>>>       INIT_LIST_HEAD(&out_q_ctx->rdy_queue);
>>>>>>>>       INIT_LIST_HEAD(&cap_q_ctx->rdy_queue);
>>>>>>>> +   INIT_LIST_HEAD(&out_q_ctx->hw_queue);
>>>>>>>> +   INIT_LIST_HEAD(&cap_q_ctx->hw_queue);
>>>>>>>>       spin_lock_init(&out_q_ctx->rdy_spinlock);
>>>>>>>>       spin_lock_init(&cap_q_ctx->rdy_spinlock);
>>>>>>>>
>>>>>>>> diff --git a/include/media/v4l2-mem2mem.h b/include/media/v4l2-mem2mem.h
>>>>>>>> index d6c8eb2b5201..2342656e582d 100644
>>>>>>>> --- a/include/media/v4l2-mem2mem.h
>>>>>>>> +++ b/include/media/v4l2-mem2mem.h
>>>>>>>> @@ -53,9 +53,16 @@ struct v4l2_m2m_dev;
>>>>>>>>     * processed
>>>>>>>>     *
>>>>>>>>     * @q:             pointer to struct &vb2_queue
>>>>>>>> - * @rdy_queue:     List of V4L2 mem-to-mem queues
>>>>>>>> + * @rdy_queue:     List of V4L2 mem-to-mem queues. If v4l2_m2m_buf_queue() is
>>>>>>>> + *         called in struct vb2_ops->buf_queue(), the buffer enqueued
>>>>>>>> + *         by user would be added to this list.
>>>>>>>>     * @rdy_spinlock: spin lock to protect the struct usage
>>>>>>>>     * @num_rdy:       number of buffers ready to be processed
>>>>>>>> + * @hw_queue:      A list for tracking the buffer is occupied by the hardware
>>>>>>>> + *                 (or device's firmware). A buffer could only be in either
>>>>>>>> + *                 this list or @rdy_queue.
>>>>>>>> + *                 Driver may choose not to use this list while uses its own
>>>>>>>> + *                 private data to do this work.
>>>>>>>>     * @buffered:      is the queue buffered?
>>>>>>>>     *
>>>>>>>>     * Queue for buffers ready to be processed as soon as this
>>>>>>>> @@ -68,6 +75,7 @@ struct v4l2_m2m_queue_ctx {
>>>>>>>>       struct list_head        rdy_queue;
>>>>>>>>       spinlock_t              rdy_spinlock;
>>>>>>>>       u8                      num_rdy;
>>>>>>>> +   struct list_head        hw_queue;
>>>>>>>>       bool                    buffered;
>>>>>>>>    };
>>>>>>>>
>>>>>>>> --
>>>>>>>> 2.17.1
>>>>>>>>
>>>>>>
>>>>
>>
>> --
>> Hsia-Jun(Randy) Li

-- 
Hsia-Jun(Randy) Li

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH 2/2] media: v4l2-mem2mem: add a list for buf used by hw
  2023-07-28  4:43           ` Tomasz Figa
  2023-07-28  7:08             ` Hsia-Jun Li
@ 2023-07-28 16:09             ` Nicolas Dufresne
  1 sibling, 0 replies; 33+ messages in thread
From: Nicolas Dufresne @ 2023-07-28 16:09 UTC (permalink / raw)
  To: Tomasz Figa, Hsia-Jun Li
  Cc: linux-media, ayaka, hans.verkuil, mchehab, laurent.pinchart,
	hiroh, hverkuil, linux-kernel

Le vendredi 28 juillet 2023 à 13:43 +0900, Tomasz Figa a écrit :
> On Fri, Jul 28, 2023 at 1:58 AM Nicolas Dufresne <nicolas@ndufresne.ca> wrote:
> > 
> > Le jeudi 27 juillet 2023 à 16:43 +0900, Tomasz Figa a écrit :
> > > On Mon, Jul 17, 2023 at 11:07 PM Nicolas Dufresne <nicolas@ndufresne.ca> wrote:
> > > > 
> > > > Le mercredi 12 juillet 2023 à 09:33 +0000, Tomasz Figa a écrit :
> > > > > On Tue, Jul 04, 2023 at 12:00:38PM +0800, Hsia-Jun Li wrote:
> > > > > > From: "Hsia-Jun(Randy) Li" <randy.li@synaptics.com>
> > > > > > 
> > > > > > Many drivers have to create its own buf_struct for a
> > > > > > vb2_queue to track such a state. Also driver has to
> > > > > > iterate over rdy_queue every times to find out a buffer
> > > > > > which is not sent to hardware(or firmware), this new
> > > > > > list just offers the driver a place to store the buffer
> > > > > > that hardware(firmware) has acknowledged.
> > > > > > 
> > > > > > One important advance about this list, it doesn't like
> > > > > > rdy_queue which both bottom half of the user calling
> > > > > > could operate it, while the v4l2 worker would as well.
> > > > > > The v4l2 core could only operate this queue when its
> > > > > > v4l2_context is not running, the driver would only
> > > > > > access this new hw_queue in its own worker.
> > > > > 
> > > > > Could you describe in what case such a list would be useful for a
> > > > > mem2mem driver?
> > > > 
> > > > Today all driver must track buffers that are "owned by the hardware". This is a
> > > > concept dictated by the m2m framework and enforced through the ACTIVE flag. All
> > > > buffers from this list must be mark as done/error/queued after streamoff of the
> > > > respective queue in order to acknowledge that they are no longer in use by the
> > > > HW. Not doing so will warn:
> > > > 
> > > >   videobuf2_common: driver bug: stop_streaming operation is leaving buf ...
> > > > 
> > > > Though, there is no queue to easily iterate them. All driver endup having their
> > > > own queue, or just leaving the buffers in the rdy_queue (which isn't better).
> > > > 
> > > 
> > > Thanks for the explanation. I see how it could be useful now.
> > > 
> > > Although I guess this is a problem specifically for hardware (or
> > > firmware) which can internally queue more than 1 buffer, right?
> > > Otherwise the current buffer could just stay at the top of the
> > > rdy_queue until it's removed by the driver's completion handler,
> > > timeout/error handler or context destruction.
> > 
> > Correct, its only an issue when you need to process multiple src buffers before
> > producing a dst buffer. If affects stateful decoder, stateful encoders and
> > deinterlacer as far as I'm aware.
> 
> Is it actually necessary to keep those buffers in a list in that case, though?
> I can see that a deinterlacer would indeed need 2 input buffers to
> perform the deinterlacing operation, but those would be just known to
> the driver, since it's running the task currently.
> For a stateful decoder, wouldn't it just consume the bitstream buffer
> (producing something partially decoded to its own internal buffers)
> and return it shortly?

In practice, in stateful decoder, we pace the consumption of input buffers,
otherwise we just endup consuming the entire video into a ring buffer, which
makes operation like seeks quite heavy and cause CPU spikes.

That being said, I'm not sure how useful a list would be for bitstream buffers.
At the moment, in my current work, I'm leaving buffers in the ready queue, and
just tagging the one I have already copied into the ring buffer. And I remove
them from the ready list, when the related data has been decoded. This is when I
actually copy the timestamp from src to dst buffer. So in short, I don't use an
extra list, but use some marking on the buffers though, to remember which one
have already been copied. This is specific to ring buffer based codecs of
course.

The one where a second list helps is for display picture buffers. When a buffer
has been filled, if its in the ready queue, I currently remove that buffer and
put it in a custom list. It will then be removed when/if the firmware decides to
display it. It may also never be displayed, and reused by the firmware. I short,
these are the frame "owned" by the firmware and containing valid pixels. The rdy
list contains free pictures buffers, and the pixels are undefined.

Maybe, and I'm ready to try, I could also leave them in ready queue and opt for
marking and a counter. As I'm using a job_ready() function, its my driver that
decides if a device_run() should be executed or not. So what matters is
basically if there is a free buffer for a new decode operation, and a counter of
filled but not displayed buffer could probably do that.

> The most realistic scenario would be for stateful encoders which could
> keep some input buffers as reference frames for further encoding, but
> then would this patch actually work for them? It would make
> __v4l2_m2m_try_queue never add the context to the job_queue if there
> are some buffers in that hw_queue list.

Encoders have 3 set of buffers, despite m2m having two queues. OUTPUT buffers
are the pictures, there is a set of internal reconstruction buffers, and finally
the CAPTURE buffers are the bitstream. Bitstream buffers are subject to
reordering, so conceptually the firmware holds more then 1, and reconstruction
buffers are completely hidden.

> 
> Maybe what I need here are actual patches modifying some existing
> drivers. Randy, would you be able to include that in the next version?
> Thanks.

Agreed.

> 
> Best regards,
> Tomasz
> 
> > 
> > Nicolas
> > 
> > > 
> > > Best regards,
> > > Tomasz
> > > 
> > > > Nicolas
> > > > > 
> > > > > > 
> > > > > > Signed-off-by: Hsia-Jun(Randy) Li <randy.li@synaptics.com>
> > > > > > ---
> > > > > >  drivers/media/v4l2-core/v4l2-mem2mem.c | 25 +++++++++++++++++--------
> > > > > >  include/media/v4l2-mem2mem.h           | 10 +++++++++-
> > > > > >  2 files changed, 26 insertions(+), 9 deletions(-)
> > > > > > 
> > > > > > diff --git a/drivers/media/v4l2-core/v4l2-mem2mem.c b/drivers/media/v4l2-core/v4l2-mem2mem.c
> > > > > > index c771aba42015..b4151147d5bd 100644
> > > > > > --- a/drivers/media/v4l2-core/v4l2-mem2mem.c
> > > > > > +++ b/drivers/media/v4l2-core/v4l2-mem2mem.c
> > > > > > @@ -321,15 +321,21 @@ static void __v4l2_m2m_try_queue(struct v4l2_m2m_dev *m2m_dev,
> > > > > >             goto job_unlock;
> > > > > >     }
> > > > > > 
> > > > > > -   src = v4l2_m2m_next_src_buf(m2m_ctx);
> > > > > > -   dst = v4l2_m2m_next_dst_buf(m2m_ctx);
> > > > > > -   if (!src && !m2m_ctx->out_q_ctx.buffered) {
> > > > > > -           dprintk("No input buffers available\n");
> > > > > > -           goto job_unlock;
> > > > > > +   if (list_empty(&m2m_ctx->out_q_ctx.hw_queue)) {
> > > > > > +           src = v4l2_m2m_next_src_buf(m2m_ctx);
> > > > > > +
> > > > > > +           if (!src && !m2m_ctx->out_q_ctx.buffered) {
> > > > > > +                   dprintk("No input buffers available\n");
> > > > > > +                   goto job_unlock;
> > > > > > +           }
> > > > > >     }
> > > > > > -   if (!dst && !m2m_ctx->cap_q_ctx.buffered) {
> > > > > > -           dprintk("No output buffers available\n");
> > > > > > -           goto job_unlock;
> > > > > > +
> > > > > > +   if (list_empty(&m2m_ctx->cap_q_ctx.hw_queue)) {
> > > > > > +           dst = v4l2_m2m_next_dst_buf(m2m_ctx);
> > > > > > +           if (!dst && !m2m_ctx->cap_q_ctx.buffered) {
> > > > > > +                   dprintk("No output buffers available\n");
> > > > > > +                   goto job_unlock;
> > > > > > +           }
> > > > > >     }
> > > > > 
> > > > > src and dst would be referenced unitialized below if neither of the
> > > > > above ifs hits...
> > > > > 
> > > > > Best regards,
> > > > > Tomasz
> > > > > 
> > > > > > 
> > > > > >     m2m_ctx->new_frame = true;
> > > > > > @@ -896,6 +902,7 @@ int v4l2_m2m_streamoff(struct file *file, struct v4l2_m2m_ctx *m2m_ctx,
> > > > > >     INIT_LIST_HEAD(&q_ctx->rdy_queue);
> > > > > >     q_ctx->num_rdy = 0;
> > > > > >     spin_unlock_irqrestore(&q_ctx->rdy_spinlock, flags);
> > > > > > +   INIT_LIST_HEAD(&q_ctx->hw_queue);
> > > > > > 
> > > > > >     if (m2m_dev->curr_ctx == m2m_ctx) {
> > > > > >             m2m_dev->curr_ctx = NULL;
> > > > > > @@ -1234,6 +1241,8 @@ struct v4l2_m2m_ctx *v4l2_m2m_ctx_init(struct v4l2_m2m_dev *m2m_dev,
> > > > > > 
> > > > > >     INIT_LIST_HEAD(&out_q_ctx->rdy_queue);
> > > > > >     INIT_LIST_HEAD(&cap_q_ctx->rdy_queue);
> > > > > > +   INIT_LIST_HEAD(&out_q_ctx->hw_queue);
> > > > > > +   INIT_LIST_HEAD(&cap_q_ctx->hw_queue);
> > > > > >     spin_lock_init(&out_q_ctx->rdy_spinlock);
> > > > > >     spin_lock_init(&cap_q_ctx->rdy_spinlock);
> > > > > > 
> > > > > > diff --git a/include/media/v4l2-mem2mem.h b/include/media/v4l2-mem2mem.h
> > > > > > index d6c8eb2b5201..2342656e582d 100644
> > > > > > --- a/include/media/v4l2-mem2mem.h
> > > > > > +++ b/include/media/v4l2-mem2mem.h
> > > > > > @@ -53,9 +53,16 @@ struct v4l2_m2m_dev;
> > > > > >   * processed
> > > > > >   *
> > > > > >   * @q:             pointer to struct &vb2_queue
> > > > > > - * @rdy_queue:     List of V4L2 mem-to-mem queues
> > > > > > + * @rdy_queue:     List of V4L2 mem-to-mem queues. If v4l2_m2m_buf_queue() is
> > > > > > + *         called in struct vb2_ops->buf_queue(), the buffer enqueued
> > > > > > + *         by user would be added to this list.
> > > > > >   * @rdy_spinlock: spin lock to protect the struct usage
> > > > > >   * @num_rdy:       number of buffers ready to be processed
> > > > > > + * @hw_queue:      A list for tracking the buffer is occupied by the hardware
> > > > > > + *                 (or device's firmware). A buffer could only be in either
> > > > > > + *                 this list or @rdy_queue.
> > > > > > + *                 Driver may choose not to use this list while uses its own
> > > > > > + *                 private data to do this work.
> > > > > >   * @buffered:      is the queue buffered?
> > > > > >   *
> > > > > >   * Queue for buffers ready to be processed as soon as this
> > > > > > @@ -68,6 +75,7 @@ struct v4l2_m2m_queue_ctx {
> > > > > >     struct list_head        rdy_queue;
> > > > > >     spinlock_t              rdy_spinlock;
> > > > > >     u8                      num_rdy;
> > > > > > +   struct list_head        hw_queue;
> > > > > >     bool                    buffered;
> > > > > >  };
> > > > > > 
> > > > > > --
> > > > > > 2.17.1
> > > > > > 
> > > > 
> > 


^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH 2/2] media: v4l2-mem2mem: add a list for buf used by hw
  2023-07-28  7:37                 ` Hsia-Jun Li
@ 2023-07-28 16:19                   ` Nicolas Dufresne
  2023-08-03 16:16                     ` Randy Li
  0 siblings, 1 reply; 33+ messages in thread
From: Nicolas Dufresne @ 2023-07-28 16:19 UTC (permalink / raw)
  To: Hsia-Jun Li, Tomasz Figa
  Cc: linux-media, ayaka, hans.verkuil, mchehab, laurent.pinchart,
	hiroh, hverkuil, linux-kernel

Le vendredi 28 juillet 2023 à 15:37 +0800, Hsia-Jun Li a écrit :
> > I think this is one reason to migrate to the stateless decoder design.
> > 
> I didn't know such plan here. I don't think the current stateless API 
> could export the reconstruction buffers for encoder or post-processing 
> buffer for decoder to us.

Someone suggested introduce auxiliary queues in our meeting in Lyon a while ago,
but I bet everyone got too busy with finalizing APIs, fixing fluster tests etc.
The suggestion felt like it would be possible to add it after the fact. This was
also being discussed in the context of supporting multi-scalers (standalone our
inline with the codec, like VC8000D+). It could also cover for primary and
secondary buffers, along with encoder primary, and reconstruction buffers, but
also auxiliary reference data. This would also be needed to properly support
Vulkan Video fwiw, and could also help with a transition to DMABuf Heaps and
memory accounting.

I've also had corridor discussion around having multi-instance media constroller
devices. It wasn't clear how to bind the media instance to the video node
instances, but assuming there is a way, it would be a tad more flexible (but
massively more complex).

Nicolas


^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH 2/2] media: v4l2-mem2mem: add a list for buf used by hw
  2023-07-28 16:19                   ` Nicolas Dufresne
@ 2023-08-03 16:16                     ` Randy Li
  2023-08-04 20:42                       ` Nicolas Dufresne
  0 siblings, 1 reply; 33+ messages in thread
From: Randy Li @ 2023-08-03 16:16 UTC (permalink / raw)
  To: Nicolas Dufresne
  Cc: linux-media, Tomasz Figa, Hsia-Jun Li, mchehab, laurent.pinchart,
	hiroh, hans.verkuil, hverkuil, linux-kernel, Benjamin Gaignard,
	p.zabel, ezequiel, Laurent Pinchart


On 2023/7/29 00:19, Nicolas Dufresne wrote:
> Le vendredi 28 juillet 2023 à 15:37 +0800, Hsia-Jun Li a écrit :
>>> I think this is one reason to migrate to the stateless decoder design.
>>>
>> I didn't know such plan here. I don't think the current stateless API
>> could export the reconstruction buffers for encoder or post-processing
>> buffer for decoder to us.
> Someone suggested introduce auxiliary queues in our meeting in Lyon a while ago,
> but I bet everyone got too busy with finalizing APIs, fixing fluster tests etc.
> The suggestion felt like it would be possible to add it after the fact. This was
> also being discussed in the context of supporting multi-scalers (standalone our
> inline with the codec, like VC8000D+). It could also cover for primary and
> secondary buffers, along with encoder primary, and reconstruction buffers, but
> also auxiliary reference data. This would also be needed to properly support
> Vulkan Video fwiw, and could also help with a transition to DMABuf Heaps and
> memory accounting.
>
> I've also had corridor discussion around having multi-instance media constroller
> devices. It wasn't clear how to bind the media instance to the video node
> instances, but assuming there is a way, it would be a tad more flexible (but
> massively more complex).

I think we should answer to those questions before we decided what we want:

A. Should a queue only has the buffers for the same format and sizes?

B. How does an application handle those drivers requests additional queue?

C. How to sync multiple buffers in a v4l2 job.

I asked the same question A when I discuss this with media: v4l2: Add 
DELETE_BUF ioctl.

If we would not add extra queue here, how does the driver filter out the 
most proper buffer for the current hardware output(CAPTURE) buffer.

If we have multiple queues in a direction, how to make driver select 
between them?


The question B is the debt we made, some applications have gotten used 
to the case they can't control the lifetime of reconstruction buffer in 
encoding or turn the post-processing off when the display pipeline could 
support tile format output.

We know allow the userspace could decide where we allocate those 
buffers, but could the userspace decided not to handle their lifetime?


The question C may more be more related to the complex case like camera 
senor and ISP. With this auxiliary queue, multiple video nodes are not 
necessary anymore.

But ISP may not request all the data finish its path, ex. the ISP are 
not satisfied with the focus point that its senor detected or the light 
level, it may just drop the image data then shot again.

Also the poll event could only tell us which direction could do the 
dequeue/enqueue work, it can't tell us which queue is ready. Should we 
introduce something likes sync point(fence fd) here?


We may lead way to V4L3 as Tomasz suggested although I don't want to 
take the risk to be. If we would make a V4L3 like thing, we have better 
to decide it correct and could handle any future problem.

>
> Nicolas
>

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH 2/2] media: v4l2-mem2mem: add a list for buf used by hw
  2023-08-03 16:16                     ` Randy Li
@ 2023-08-04 20:42                       ` Nicolas Dufresne
  0 siblings, 0 replies; 33+ messages in thread
From: Nicolas Dufresne @ 2023-08-04 20:42 UTC (permalink / raw)
  To: Randy Li
  Cc: linux-media, Tomasz Figa, Hsia-Jun Li, mchehab, laurent.pinchart,
	hiroh, hans.verkuil, hverkuil, linux-kernel, Benjamin Gaignard,
	p.zabel, ezequiel

Hi Randy,

Le vendredi 04 août 2023 à 00:16 +0800, Randy Li a écrit :
> On 2023/7/29 00:19, Nicolas Dufresne wrote:
> > Le vendredi 28 juillet 2023 à 15:37 +0800, Hsia-Jun Li a écrit :
> > > > I think this is one reason to migrate to the stateless decoder design.
> > > > 
> > > I didn't know such plan here. I don't think the current stateless API
> > > could export the reconstruction buffers for encoder or post-processing
> > > buffer for decoder to us.
> > Someone suggested introduce auxiliary queues in our meeting in Lyon a while ago,
> > but I bet everyone got too busy with finalizing APIs, fixing fluster tests etc.
> > The suggestion felt like it would be possible to add it after the fact. This was
> > also being discussed in the context of supporting multi-scalers (standalone our
> > inline with the codec, like VC8000D+). It could also cover for primary and
> > secondary buffers, along with encoder primary, and reconstruction buffers, but
> > also auxiliary reference data. This would also be needed to properly support
> > Vulkan Video fwiw, and could also help with a transition to DMABuf Heaps and
> > memory accounting.
> > 
> > I've also had corridor discussion around having multi-instance media constroller
> > devices. It wasn't clear how to bind the media instance to the video node
> > instances, but assuming there is a way, it would be a tad more flexible (but
> > massively more complex).
> 
> I think we should answer to those questions before we decided what we want:
> 
> A. Should a queue only has the buffers for the same format and sizes?

I initially started answering these, but ended up concluding this is more some
sort of personal notes. I believe the discussion is diverging. Remember that in
an existing API, one cannot fix all theoretical issues in one go. In order to
move forward, you have to tackle very specific use case and find a way forward.
If you are to break compatibility as much as you suggest, you'd rather look into
writing a new API.

[...]

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH 0/2] Improve V4L2 M2M job scheduler
  2023-07-04  4:00 [PATCH 0/2] Improve V4L2 M2M job scheduler Hsia-Jun Li
  2023-07-04  4:00 ` [PATCH 1/2] [RESEND] media: v4l2-mem2mem: allow device run without buf Hsia-Jun Li
  2023-07-04  4:00 ` [PATCH 2/2] media: v4l2-mem2mem: add a list for buf used by hw Hsia-Jun Li
@ 2023-08-18 14:45 ` Hans Verkuil
  2023-08-22  7:59   ` Tomasz Figa
  2 siblings, 1 reply; 33+ messages in thread
From: Hans Verkuil @ 2023-08-18 14:45 UTC (permalink / raw)
  To: Hsia-Jun Li, linux-media
  Cc: ayaka, hans.verkuil, tfiga, mchehab, laurent.pinchart, hiroh,
	linux-kernel, nicolas

On 04/07/2023 06:00, Hsia-Jun Li wrote:
> From: "Hsia-Jun(Randy) Li" <randy.li@synaptics.com>
> 
> The first patch is an old patch, I resend it again.
> I want to make the work thats parses the bitstream
> to extract the sequence information or video resolution
> as a part of V4L2 schedule. Such a work would also
> consume the device's resources likes remote CPU
> time.
> 
> Although reuse a flag which no current driver may
> not be a good idea. I could add a new flag for that
> if people like that.
> 
> The second is a patch offering a generic solution
> for tracking buffers which have been pushed to
> hardware(or firmware). It didn't record which buffer
> that hardware(firmware) still holds for future
> decoding(likes the reference buffer), while it
> has been sent to the user(dequeue). We may need
> a flag for this work.

I am dropping this series from patchwork: clearly this generated
a lot of discussion, and I think that needs to come to a conclusion.

BTW, I believe that at minimum the codec-specific parts in
v4l2-mem2mem.c should be split off in their own source (v4l2-m2m-codec.c?).

I agree with Tomasz that mem2mem.c was originally for simple m2m devices,
and adding all sorts of codec specific code to that source doesn't make
it easier to follow.

Regards,

	Hans

> 
> Hsia-Jun(Randy) Li (1):
>   media: v4l2-mem2mem: add a list for buf used by hw
> 
> Randy Li (1):
>   media: v4l2-mem2mem: allow device run without buf
> 
>  drivers/media/v4l2-core/v4l2-mem2mem.c | 30 +++++++++++++++++---------
>  include/media/v4l2-mem2mem.h           | 10 ++++++++-
>  2 files changed, 29 insertions(+), 11 deletions(-)
> 


^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH 0/2] Improve V4L2 M2M job scheduler
  2023-08-18 14:45 ` [PATCH 0/2] Improve V4L2 M2M job scheduler Hans Verkuil
@ 2023-08-22  7:59   ` Tomasz Figa
  0 siblings, 0 replies; 33+ messages in thread
From: Tomasz Figa @ 2023-08-22  7:59 UTC (permalink / raw)
  To: Hans Verkuil
  Cc: Hsia-Jun Li, linux-media, ayaka, hans.verkuil, mchehab,
	laurent.pinchart, hiroh, linux-kernel, nicolas

On Fri, Aug 18, 2023 at 11:45 PM Hans Verkuil <hverkuil@xs4all.nl> wrote:
>
> On 04/07/2023 06:00, Hsia-Jun Li wrote:
> > From: "Hsia-Jun(Randy) Li" <randy.li@synaptics.com>
> >
> > The first patch is an old patch, I resend it again.
> > I want to make the work thats parses the bitstream
> > to extract the sequence information or video resolution
> > as a part of V4L2 schedule. Such a work would also
> > consume the device's resources likes remote CPU
> > time.
> >
> > Although reuse a flag which no current driver may
> > not be a good idea. I could add a new flag for that
> > if people like that.
> >
> > The second is a patch offering a generic solution
> > for tracking buffers which have been pushed to
> > hardware(or firmware). It didn't record which buffer
> > that hardware(firmware) still holds for future
> > decoding(likes the reference buffer), while it
> > has been sent to the user(dequeue). We may need
> > a flag for this work.
>
> I am dropping this series from patchwork: clearly this generated
> a lot of discussion, and I think that needs to come to a conclusion.
>
> BTW, I believe that at minimum the codec-specific parts in
> v4l2-mem2mem.c should be split off in their own source (v4l2-m2m-codec.c?).

I like the idea. This way we could possibly evolve the framework more
towards the codec helpers, reusing as much code as possible, but also
keeping the basic implementation simple.

>
> I agree with Tomasz that mem2mem.c was originally for simple m2m devices,
> and adding all sorts of codec specific code to that source doesn't make
> it easier to follow.
>
> Regards,
>
>         Hans
>
> >
> > Hsia-Jun(Randy) Li (1):
> >   media: v4l2-mem2mem: add a list for buf used by hw
> >
> > Randy Li (1):
> >   media: v4l2-mem2mem: allow device run without buf
> >
> >  drivers/media/v4l2-core/v4l2-mem2mem.c | 30 +++++++++++++++++---------
> >  include/media/v4l2-mem2mem.h           | 10 ++++++++-
> >  2 files changed, 29 insertions(+), 11 deletions(-)
> >
>

^ permalink raw reply	[flat|nested] 33+ messages in thread

end of thread, other threads:[~2023-08-22  8:00 UTC | newest]

Thread overview: 33+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-07-04  4:00 [PATCH 0/2] Improve V4L2 M2M job scheduler Hsia-Jun Li
2023-07-04  4:00 ` [PATCH 1/2] [RESEND] media: v4l2-mem2mem: allow device run without buf Hsia-Jun Li
2023-07-07 19:14   ` Nicolas Dufresne
2023-07-12  9:31     ` Tomasz Figa
2023-07-12  9:44       ` Sebastian Fricke
2023-07-13  3:13         ` Tomasz Figa
2023-07-17 14:00       ` Nicolas Dufresne
2023-07-21  8:56         ` Hsia-Jun Li
2023-07-21 16:22           ` Nicolas Dufresne
2023-07-24 17:29             ` Randy Li
2023-07-04  4:00 ` [PATCH 2/2] media: v4l2-mem2mem: add a list for buf used by hw Hsia-Jun Li
2023-07-07 19:20   ` Nicolas Dufresne
2023-07-11  8:54     ` Randy Li
2023-07-11  6:26   ` Dan Carpenter
2023-07-12  9:33   ` Tomasz Figa
2023-07-17  7:14     ` Hsia-Jun Li
2023-07-27  7:25       ` Tomasz Figa
2023-07-27  7:33         ` Hsia-Jun Li
2023-07-27  7:54           ` Tomasz Figa
2023-07-17 14:07     ` Nicolas Dufresne
2023-07-18  3:53       ` Hsia-Jun Li
2023-07-27  7:43       ` Tomasz Figa
2023-07-27 16:58         ` Nicolas Dufresne
2023-07-28  4:43           ` Tomasz Figa
2023-07-28  7:08             ` Hsia-Jun Li
2023-07-28  7:26               ` Tomasz Figa
2023-07-28  7:37                 ` Hsia-Jun Li
2023-07-28 16:19                   ` Nicolas Dufresne
2023-08-03 16:16                     ` Randy Li
2023-08-04 20:42                       ` Nicolas Dufresne
2023-07-28 16:09             ` Nicolas Dufresne
2023-08-18 14:45 ` [PATCH 0/2] Improve V4L2 M2M job scheduler Hans Verkuil
2023-08-22  7:59   ` Tomasz Figa

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).