diff --git a/drivers/staging/media/rkvdec/rkvdec.c b/drivers/staging/media/rkvdec/rkvdec.c index bf00fe6534a3..4fd4a2907da7 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 *)) -{ - struct rkvdec_ctx *ctx = fh_to_rkvdec_ctx(priv); - struct vb2_queue *vq; - - if (!try_fmt) - return -EINVAL; - - vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, f->type); - 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); + struct vb2_queue *vq; int ret; - ret = rkvdec_s_fmt(file, priv, f, rkvdec_try_capture_fmt); + /* 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; + + 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;