Le lundi 09 septembre 2024 à 19:25 +0000, Jonas Karlman a écrit : > Add support for a get_image_fmt() ops that return the required image > format. > > The CAPTURE format is reset when required image format changes and the > buffer queue is not busy. > > Signed-off-by: Jonas Karlman <jonas@xxxxxxxxx> > Tested-by: Nicolas Dufresne <nicolas.dufresne@xxxxxxxxxxxxx> > Tested-by: Christopher Obbard <chris.obbard@xxxxxxxxxxxxx> Looks good to me. Reviewed-by: Nicolas Dufresne <nicolas.dufresne@xxxxxxxxxxxxx> > --- > v6: > - No change > > v5: > - Collect t-b tags > > v4: > - Change fmt_opaque into an image format > - Split patch into two > > v3: > - New patch > --- > drivers/staging/media/rkvdec/rkvdec.c | 49 +++++++++++++++++++++++++-- > drivers/staging/media/rkvdec/rkvdec.h | 2 ++ > 2 files changed, 49 insertions(+), 2 deletions(-) > > diff --git a/drivers/staging/media/rkvdec/rkvdec.c b/drivers/staging/media/rkvdec/rkvdec.c > index 467fc05b347a..8df49ee12820 100644 > --- a/drivers/staging/media/rkvdec/rkvdec.c > +++ b/drivers/staging/media/rkvdec/rkvdec.c > @@ -111,15 +111,60 @@ static int rkvdec_try_ctrl(struct v4l2_ctrl *ctrl) > { > struct rkvdec_ctx *ctx = container_of(ctrl->handler, struct rkvdec_ctx, ctrl_hdl); > const struct rkvdec_coded_fmt_desc *desc = ctx->coded_fmt_desc; > + struct v4l2_pix_format_mplane *pix_mp = &ctx->decoded_fmt.fmt.pix_mp; > + enum rkvdec_image_fmt image_fmt; > + struct vb2_queue *vq; > + int ret; > + > + if (desc->ops->try_ctrl) { > + ret = desc->ops->try_ctrl(ctx, ctrl); > + if (ret) > + return ret; > + } > + > + if (!desc->ops->get_image_fmt) > + return 0; > > - if (desc->ops->try_ctrl) > - return desc->ops->try_ctrl(ctx, ctrl); > + image_fmt = desc->ops->get_image_fmt(ctx, ctrl); > + if (ctx->image_fmt == image_fmt) > + return 0; > + > + if (rkvdec_is_valid_fmt(ctx, pix_mp->pixelformat, image_fmt)) > + return 0; > + > + /* format change not allowed when queue is busy */ > + vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, > + V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); > + if (vb2_is_busy(vq)) > + return -EINVAL; > + > + return 0; > +} > + > +static int rkvdec_s_ctrl(struct v4l2_ctrl *ctrl) > +{ > + struct rkvdec_ctx *ctx = container_of(ctrl->handler, struct rkvdec_ctx, ctrl_hdl); > + const struct rkvdec_coded_fmt_desc *desc = ctx->coded_fmt_desc; > + struct v4l2_pix_format_mplane *pix_mp = &ctx->decoded_fmt.fmt.pix_mp; > + enum rkvdec_image_fmt image_fmt; > + > + if (!desc->ops->get_image_fmt) > + return 0; > + > + image_fmt = desc->ops->get_image_fmt(ctx, ctrl); > + if (ctx->image_fmt == image_fmt) > + return 0; > + > + ctx->image_fmt = image_fmt; > + if (!rkvdec_is_valid_fmt(ctx, pix_mp->pixelformat, ctx->image_fmt)) > + rkvdec_reset_decoded_fmt(ctx); > > return 0; > } > > static const struct v4l2_ctrl_ops rkvdec_ctrl_ops = { > .try_ctrl = rkvdec_try_ctrl, > + .s_ctrl = rkvdec_s_ctrl, > }; > > static const struct rkvdec_ctrl_desc rkvdec_h264_ctrl_descs[] = { > diff --git a/drivers/staging/media/rkvdec/rkvdec.h b/drivers/staging/media/rkvdec/rkvdec.h > index 6f8cf50c5d99..e466a2753ccf 100644 > --- a/drivers/staging/media/rkvdec/rkvdec.h > +++ b/drivers/staging/media/rkvdec/rkvdec.h > @@ -73,6 +73,8 @@ struct rkvdec_coded_fmt_ops { > struct vb2_v4l2_buffer *dst_buf, > enum vb2_buffer_state result); > int (*try_ctrl)(struct rkvdec_ctx *ctx, struct v4l2_ctrl *ctrl); > + enum rkvdec_image_fmt (*get_image_fmt)(struct rkvdec_ctx *ctx, > + struct v4l2_ctrl *ctrl); > }; > > enum rkvdec_image_fmt {