The mem-to-mem stateless decoder API specifies support for dynamic
resolution changes. In particular, the decoder should accept format
changes on the OUTPUT queue even when buffers have been allocated,
as long as it is not streaming.
Relax restrictions for S_FMT as described in the previous paragraph,
and as long as the codec format remains the same. This aligns it with
the Hantro and Cedrus decoders. This change was mostly based on commit
ae02d49493b5 ("media: hantro: Fix s_fmt for dynamic resolution changes").
Since rkvdec_s_fmt() is now just a wrapper around the output/capture
variants without any additional shared functionality, drop the wrapper
and call the respective functions directly.
Fixes: cd33c830448b ("media: rkvdec: Add the rkvdec driver")
Cc: <[email protected]>
Signed-off-by: Chen-Yu Tsai <[email protected]>
---
drivers/staging/media/rkvdec/rkvdec.c | 40 +++++++++++++--------------
1 file changed, 20 insertions(+), 20 deletions(-)
diff --git a/drivers/staging/media/rkvdec/rkvdec.c b/drivers/staging/media/rkvdec/rkvdec.c
index 7131156c1f2c..3f3f96488d74 100644
--- a/drivers/staging/media/rkvdec/rkvdec.c
+++ b/drivers/staging/media/rkvdec/rkvdec.c
@@ -280,31 +280,20 @@ static int rkvdec_try_output_fmt(struct file *file, void *priv,
return 0;
}
-static int rkvdec_s_fmt(struct file *file, void *priv,
- struct v4l2_format *f,
- int (*try_fmt)(struct file *, void *,
- struct v4l2_format *))
+static int rkvdec_s_capture_fmt(struct file *file, void *priv,
+ struct v4l2_format *f)
{
struct rkvdec_ctx *ctx = fh_to_rkvdec_ctx(priv);
struct vb2_queue *vq;
+ int ret;
- if (!try_fmt)
- return -EINVAL;
-
- vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, f->type);
+ /* Change not allowed if queue is busy */
+ vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx,
+ V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
if (vb2_is_busy(vq))
return -EBUSY;
- return try_fmt(file, priv, f);
-}
-
-static int rkvdec_s_capture_fmt(struct file *file, void *priv,
- struct v4l2_format *f)
-{
- struct rkvdec_ctx *ctx = fh_to_rkvdec_ctx(priv);
- int ret;
-
- ret = rkvdec_s_fmt(file, priv, f, rkvdec_try_capture_fmt);
+ ret = rkvdec_try_capture_fmt(file, priv, f);
if (ret)
return ret;
@@ -319,9 +308,20 @@ static int rkvdec_s_output_fmt(struct file *file, void *priv,
struct v4l2_m2m_ctx *m2m_ctx = ctx->fh.m2m_ctx;
const struct rkvdec_coded_fmt_desc *desc;
struct v4l2_format *cap_fmt;
- struct vb2_queue *peer_vq;
+ struct vb2_queue *peer_vq, *vq;
int ret;
+ /*
+ * In order to support dynamic resolution change, the decoder admits
+ * a resolution change, as long as the pixelformat remains. Can't be
+ * done if streaming.
+ */
+ vq = v4l2_m2m_get_vq(m2m_ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
+ if (vb2_is_streaming(vq) ||
+ (vb2_is_busy(vq) &&
+ f->fmt.pix_mp.pixelformat != ctx->coded_fmt.fmt.pix_mp.pixelformat))
+ return -EBUSY;
+
/*
* Since format change on the OUTPUT queue will reset the CAPTURE
* queue, we can't allow doing so when the CAPTURE queue has buffers
@@ -331,7 +331,7 @@ static int rkvdec_s_output_fmt(struct file *file, void *priv,
if (vb2_is_busy(peer_vq))
return -EBUSY;
- ret = rkvdec_s_fmt(file, priv, f, rkvdec_try_output_fmt);
+ ret = rkvdec_try_output_fmt(file, priv, f);
if (ret)
return ret;
--
2.33.0.882.g93a45727a2-goog
Le vendredi 08 octobre 2021 à 18:04 +0800, Chen-Yu Tsai a écrit :
> The mem-to-mem stateless decoder API specifies support for dynamic
> resolution changes. In particular, the decoder should accept format
> changes on the OUTPUT queue even when buffers have been allocated,
> as long as it is not streaming.
As commented in the code, it also requires the CAPTURE side not to be busy, not
sure if its worth clarifying, I don't really mind.
>
> Relax restrictions for S_FMT as described in the previous paragraph,
> and as long as the codec format remains the same. This aligns it with
> the Hantro and Cedrus decoders. This change was mostly based on commit
> ae02d49493b5 ("media: hantro: Fix s_fmt for dynamic resolution changes").
>
> Since rkvdec_s_fmt() is now just a wrapper around the output/capture
> variants without any additional shared functionality, drop the wrapper
> and call the respective functions directly.
>
> Fixes: cd33c830448b ("media: rkvdec: Add the rkvdec driver")
> Cc: <[email protected]>
> Signed-off-by: Chen-Yu Tsai <[email protected]>
Reviewed-by: Nicolas Dufresne <[email protected]>
> ---
> drivers/staging/media/rkvdec/rkvdec.c | 40 +++++++++++++--------------
> 1 file changed, 20 insertions(+), 20 deletions(-)
>
> diff --git a/drivers/staging/media/rkvdec/rkvdec.c b/drivers/staging/media/rkvdec/rkvdec.c
> index 7131156c1f2c..3f3f96488d74 100644
> --- a/drivers/staging/media/rkvdec/rkvdec.c
> +++ b/drivers/staging/media/rkvdec/rkvdec.c
> @@ -280,31 +280,20 @@ static int rkvdec_try_output_fmt(struct file *file, void *priv,
> return 0;
> }
>
> -static int rkvdec_s_fmt(struct file *file, void *priv,
> - struct v4l2_format *f,
> - int (*try_fmt)(struct file *, void *,
> - struct v4l2_format *))
> +static int rkvdec_s_capture_fmt(struct file *file, void *priv,
> + struct v4l2_format *f)
> {
> struct rkvdec_ctx *ctx = fh_to_rkvdec_ctx(priv);
> struct vb2_queue *vq;
> + int ret;
>
> - if (!try_fmt)
> - return -EINVAL;
> -
> - vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, f->type);
> + /* Change not allowed if queue is busy */
> + vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx,
> + V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
> if (vb2_is_busy(vq))
> return -EBUSY;
>
> - return try_fmt(file, priv, f);
> -}
> -
> -static int rkvdec_s_capture_fmt(struct file *file, void *priv,
> - struct v4l2_format *f)
> -{
> - struct rkvdec_ctx *ctx = fh_to_rkvdec_ctx(priv);
> - int ret;
> -
> - ret = rkvdec_s_fmt(file, priv, f, rkvdec_try_capture_fmt);
> + ret = rkvdec_try_capture_fmt(file, priv, f);
> if (ret)
> return ret;
>
> @@ -319,9 +308,20 @@ static int rkvdec_s_output_fmt(struct file *file, void *priv,
> struct v4l2_m2m_ctx *m2m_ctx = ctx->fh.m2m_ctx;
> const struct rkvdec_coded_fmt_desc *desc;
> struct v4l2_format *cap_fmt;
> - struct vb2_queue *peer_vq;
> + struct vb2_queue *peer_vq, *vq;
> int ret;
>
> + /*
> + * In order to support dynamic resolution change, the decoder admits
> + * a resolution change, as long as the pixelformat remains. Can't be
> + * done if streaming.
> + */
> + vq = v4l2_m2m_get_vq(m2m_ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
> + if (vb2_is_streaming(vq) ||
> + (vb2_is_busy(vq) &&
> + f->fmt.pix_mp.pixelformat != ctx->coded_fmt.fmt.pix_mp.pixelformat))
> + return -EBUSY;
> +
> /*
> * Since format change on the OUTPUT queue will reset the CAPTURE
> * queue, we can't allow doing so when the CAPTURE queue has buffers
> @@ -331,7 +331,7 @@ static int rkvdec_s_output_fmt(struct file *file, void *priv,
> if (vb2_is_busy(peer_vq))
> return -EBUSY;
>
> - ret = rkvdec_s_fmt(file, priv, f, rkvdec_try_output_fmt);
> + ret = rkvdec_try_output_fmt(file, priv, f);
> if (ret)
> return ret;
>
Hi Chen-Yu,
On Fri, Oct 08, 2021 at 06:04:23PM +0800, Chen-Yu Tsai wrote:
> The mem-to-mem stateless decoder API specifies support for dynamic
> resolution changes. In particular, the decoder should accept format
> changes on the OUTPUT queue even when buffers have been allocated,
> as long as it is not streaming.
>
> Relax restrictions for S_FMT as described in the previous paragraph,
> and as long as the codec format remains the same. This aligns it with
> the Hantro and Cedrus decoders. This change was mostly based on commit
> ae02d49493b5 ("media: hantro: Fix s_fmt for dynamic resolution changes").
>
> Since rkvdec_s_fmt() is now just a wrapper around the output/capture
> variants without any additional shared functionality, drop the wrapper
> and call the respective functions directly.
>
> Fixes: cd33c830448b ("media: rkvdec: Add the rkvdec driver")
> Cc: <[email protected]>
> Signed-off-by: Chen-Yu Tsai <[email protected]>
Reviewed-by: Ezequiel Garcia <[email protected]>
Seems we forgot to port Hantro changes over here, so thanks a lot
for picking this up.
Ezequiel
> ---
> drivers/staging/media/rkvdec/rkvdec.c | 40 +++++++++++++--------------
> 1 file changed, 20 insertions(+), 20 deletions(-)
>
> diff --git a/drivers/staging/media/rkvdec/rkvdec.c b/drivers/staging/media/rkvdec/rkvdec.c
> index 7131156c1f2c..3f3f96488d74 100644
> --- a/drivers/staging/media/rkvdec/rkvdec.c
> +++ b/drivers/staging/media/rkvdec/rkvdec.c
> @@ -280,31 +280,20 @@ static int rkvdec_try_output_fmt(struct file *file, void *priv,
> return 0;
> }
>
> -static int rkvdec_s_fmt(struct file *file, void *priv,
> - struct v4l2_format *f,
> - int (*try_fmt)(struct file *, void *,
> - struct v4l2_format *))
> +static int rkvdec_s_capture_fmt(struct file *file, void *priv,
> + struct v4l2_format *f)
> {
> struct rkvdec_ctx *ctx = fh_to_rkvdec_ctx(priv);
> struct vb2_queue *vq;
> + int ret;
>
> - if (!try_fmt)
> - return -EINVAL;
> -
> - vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, f->type);
> + /* Change not allowed if queue is busy */
> + vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx,
> + V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
> if (vb2_is_busy(vq))
> return -EBUSY;
>
> - return try_fmt(file, priv, f);
> -}
> -
> -static int rkvdec_s_capture_fmt(struct file *file, void *priv,
> - struct v4l2_format *f)
> -{
> - struct rkvdec_ctx *ctx = fh_to_rkvdec_ctx(priv);
> - int ret;
> -
> - ret = rkvdec_s_fmt(file, priv, f, rkvdec_try_capture_fmt);
> + ret = rkvdec_try_capture_fmt(file, priv, f);
> if (ret)
> return ret;
>
> @@ -319,9 +308,20 @@ static int rkvdec_s_output_fmt(struct file *file, void *priv,
> struct v4l2_m2m_ctx *m2m_ctx = ctx->fh.m2m_ctx;
> const struct rkvdec_coded_fmt_desc *desc;
> struct v4l2_format *cap_fmt;
> - struct vb2_queue *peer_vq;
> + struct vb2_queue *peer_vq, *vq;
> int ret;
>
> + /*
> + * In order to support dynamic resolution change, the decoder admits
> + * a resolution change, as long as the pixelformat remains. Can't be
> + * done if streaming.
> + */
> + vq = v4l2_m2m_get_vq(m2m_ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
> + if (vb2_is_streaming(vq) ||
> + (vb2_is_busy(vq) &&
> + f->fmt.pix_mp.pixelformat != ctx->coded_fmt.fmt.pix_mp.pixelformat))
> + return -EBUSY;
> +
> /*
> * Since format change on the OUTPUT queue will reset the CAPTURE
> * queue, we can't allow doing so when the CAPTURE queue has buffers
> @@ -331,7 +331,7 @@ static int rkvdec_s_output_fmt(struct file *file, void *priv,
> if (vb2_is_busy(peer_vq))
> return -EBUSY;
>
> - ret = rkvdec_s_fmt(file, priv, f, rkvdec_try_output_fmt);
> + ret = rkvdec_try_output_fmt(file, priv, f);
> if (ret)
> return ret;
>
> --
> 2.33.0.882.g93a45727a2-goog
>