media: mediatek: vcodec: add decoder command to support stateless decoder
authorYunfei Dong <yunfei.dong@mediatek.com>
Sat, 16 Mar 2024 08:13:44 +0000 (16:13 +0800)
committerHans Verkuil <hverkuil-cisco@xs4all.nl>
Mon, 10 Jun 2024 08:24:10 +0000 (10:24 +0200)
The supported decoder commands are different for stateless and
stateful architectures. Add stateless decoder commands to fix
the v4l2-compliance test error below.

Codec ioctls:
    VIDIOC_ENCODER_CMD returned -1 (Inappropriate ioctl for device)
    VIDIOC_TRY_ENCODER_CMD returned -1 (Inappropriate ioctl for device)
 test VIDIOC_(TRY_)ENCODER_CMD: OK (Not Supported)
    VIDIOC_G_ENC_INDEX returned -1 (Inappropriate ioctl for device)
 test VIDIOC_G_ENC_INDEX: OK (Not Supported)
    VIDIOC_DECODER_CMD returned -1 (Invalid argument)
    VIDIOC_TRY_DECODER_CMD returned -1 (Invalid argument)
    VIDIOC_TRY_DECODER_CMD returned -1 (Invalid argument)
    fail: v4l2-test-codecs.cpp(126): ret
 test VIDIOC_(TRY_)DECODER_CMD: FAIL

Signed-off-by: Yunfei Dong <yunfei.dong@mediatek.com>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Signed-off-by: Sebastian Fricke <sebastian.fricke@collabora.com>
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec.c

index 9107707de6c456d47e1c08943a8eb4d0c91e939e..98838217b97d45ed2b5431fdf87c94e0ff79fc57 100644 (file)
@@ -80,21 +80,18 @@ static struct mtk_q_data *mtk_vdec_get_q_data(struct mtk_vcodec_dec_ctx *ctx,
        return &ctx->q_data[MTK_Q_DATA_DST];
 }
 
-static int vidioc_try_decoder_cmd(struct file *file, void *priv,
-                               struct v4l2_decoder_cmd *cmd)
+static int stateful_try_decoder_cmd(struct file *file, void *priv, struct v4l2_decoder_cmd *cmd)
 {
        return v4l2_m2m_ioctl_try_decoder_cmd(file, priv, cmd);
 }
 
-
-static int vidioc_decoder_cmd(struct file *file, void *priv,
-                               struct v4l2_decoder_cmd *cmd)
+static int stateful_decoder_cmd(struct file *file, void *priv, struct v4l2_decoder_cmd *cmd)
 {
        struct mtk_vcodec_dec_ctx *ctx = fh_to_dec_ctx(priv);
        struct vb2_queue *src_vq, *dst_vq;
        int ret;
 
-       ret = vidioc_try_decoder_cmd(file, priv, cmd);
+       ret = stateful_try_decoder_cmd(file, priv, cmd);
        if (ret)
                return ret;
 
@@ -128,6 +125,57 @@ static int vidioc_decoder_cmd(struct file *file, void *priv,
        return 0;
 }
 
+static int stateless_try_decoder_cmd(struct file *file, void *priv, struct v4l2_decoder_cmd *cmd)
+{
+       return v4l2_m2m_ioctl_stateless_try_decoder_cmd(file, priv, cmd);
+}
+
+static int stateless_decoder_cmd(struct file *file, void *priv, struct v4l2_decoder_cmd *cmd)
+{
+       struct mtk_vcodec_dec_ctx *ctx = fh_to_dec_ctx(priv);
+       int ret;
+
+       ret = v4l2_m2m_ioctl_stateless_try_decoder_cmd(file, priv, cmd);
+       if (ret)
+               return ret;
+
+       mtk_v4l2_vdec_dbg(3, ctx, "decoder cmd=%u", cmd->cmd);
+       switch (cmd->cmd) {
+       case V4L2_DEC_CMD_FLUSH:
+               /*
+                * If the flag of the output buffer is equals V4L2_BUF_FLAG_M2M_HOLD_CAPTURE_BUF,
+                * this command will prevent dequeueing the capture buffer containing the last
+                * decoded frame. Or do nothing
+                */
+               break;
+       default:
+               mtk_v4l2_vdec_err(ctx, "invalid stateless decoder cmd=%u", cmd->cmd);
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+static int vidioc_try_decoder_cmd(struct file *file, void *priv, struct v4l2_decoder_cmd *cmd)
+{
+       struct mtk_vcodec_dec_ctx *ctx = fh_to_dec_ctx(priv);
+
+       if (ctx->dev->vdec_pdata->uses_stateless_api)
+               return stateless_try_decoder_cmd(file, priv, cmd);
+
+       return stateful_try_decoder_cmd(file, priv, cmd);
+}
+
+static int vidioc_decoder_cmd(struct file *file, void *priv, struct v4l2_decoder_cmd *cmd)
+{
+       struct mtk_vcodec_dec_ctx *ctx = fh_to_dec_ctx(priv);
+
+       if (ctx->dev->vdec_pdata->uses_stateless_api)
+               return stateless_decoder_cmd(file, priv, cmd);
+
+       return stateful_decoder_cmd(file, priv, cmd);
+}
+
 void mtk_vdec_unlock(struct mtk_vcodec_dec_ctx *ctx)
 {
        mutex_unlock(&ctx->dev->dec_mutex[ctx->hw_id]);