[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20230101-patch-series-v2-6-2-rc1-v2-11-fa1897efac14@collabora.com>
Date: Thu, 12 Jan 2023 13:56:26 +0100
From: Sebastian Fricke <sebastian.fricke@...labora.com>
To: Mauro Carvalho Chehab <mchehab@...nel.org>,
Ezequiel Garcia <ezequiel@...guardiasur.com.ar>,
Greg Kroah-Hartman <gregkh@...uxfoundation.org>
Cc: linux-media@...r.kernel.org, linux-kernel@...r.kernel.org,
linux-rockchip@...ts.infradead.org, linux-staging@...ts.linux.dev,
Jonas Karlman <jonas@...boo.se>,
Alex Bee <knaerzche@...il.com>,
Nicolas Dufresne <nicolas.dufresne@...labora.com>,
Collabora Kernel-domain <kernel@...labora.com>,
Robert Beckett <bob.beckett@...labora.com>,
Laurent Pinchart <laurent.pinchart@...asonboard.com>,
Andrzej Pietrasiewicz <andrzej.p@...labora.com>,
Benjamin Gaignard <benjamin.gaignard@...labora.com>,
Sebastian Fricke <sebastian.fricke@...labora.com>
Subject: [PATCH v2 11/12] staging: media: rkvdec: Enable S_CTRL IOCTL
Enable user-space to set the SPS of the current byte-stream on the
decoder. This action will enable the decoder to pick the optimal
pixel-format for the capture queue, whenever it is required.
Signed-off-by: Sebastian Fricke <sebastian.fricke@...labora.com>
Signed-off-by: Jonas Karlman <jonas@...boo.se>
---
drivers/staging/media/rkvdec/rkvdec.c | 81 +++++++++++++++++++++++++++++++++++
1 file changed, 81 insertions(+)
diff --git a/drivers/staging/media/rkvdec/rkvdec.c b/drivers/staging/media/rkvdec/rkvdec.c
index b303c6e0286d..3d413c5ad1d2 100644
--- a/drivers/staging/media/rkvdec/rkvdec.c
+++ b/drivers/staging/media/rkvdec/rkvdec.c
@@ -93,6 +93,79 @@ static int rkvdec_get_sps_attributes(struct rkvdec_ctx *ctx, void *sps,
return 0;
}
+static int rkvdec_set_sps(struct rkvdec_ctx *ctx, struct v4l2_ctrl *ctrl)
+{
+ struct v4l2_pix_format_mplane *pix_mp;
+ struct sps_attributes attributes = {0};
+ void *new_sps = NULL;
+
+ /*
+ * SPS structures are not filled until the control handler is set up
+ */
+ if (!ctx->fh.ctrl_handler)
+ return 0;
+
+ switch (ctrl->id) {
+ case V4L2_CID_STATELESS_H264_SPS:
+ new_sps = (void *)ctrl->p_new.p_h264_sps;
+ break;
+ case V4L2_CID_STATELESS_HEVC_SPS:
+ new_sps = (void *)ctrl->p_new.p_hevc_sps;
+ break;
+ default:
+ dev_err(ctx->dev->dev, "Unsupported stateless control ID: %x\n", ctrl->id);
+ return -EINVAL;
+ };
+ rkvdec_get_sps_attributes(ctx, new_sps, &attributes);
+
+ /*
+ * Providing an empty SPS is valid but we do not store it.
+ */
+ if (attributes.width == 0 && attributes.height == 0)
+ return 0;
+
+ pix_mp = &ctx->decoded_fmt.fmt.pix_mp;
+
+ /*
+ * SPS must match the provided format dimension, if it doesn't userspace has to
+ * first reset the output format
+ */
+ if ((attributes.width > pix_mp->width) || (attributes.height > pix_mp->height)) {
+ dev_err(ctx->dev->dev,
+ "Dimension mismatch. [%s SPS] W: %d, H: %d, [Format] W: %d, H: %d)\n",
+ ctrl->id == V4L2_CID_STATELESS_HEVC_SPS ? "HEVC" : "H264",
+ attributes.width, attributes.height, pix_mp->width, pix_mp->height);
+ return -EINVAL;
+ }
+
+ if (ctx->sps && pix_mp->pixelformat == rkvdec_get_valid_fmt(ctx)) {
+ /*
+ * Userspace is allowed to change the SPS at any point, if the
+ * pixel format doesn't differ from the format in the context,
+ * just accept the change even if buffers are queued
+ */
+ ctx->sps = new_sps;
+ } else {
+ /*
+ * Do not accept changing the SPS, while buffers are queued,
+ * when the new SPS would cause switching the CAPTURE pixel format
+ */
+ if (pix_mp->pixelformat != rkvdec_get_valid_fmt(ctx)) {
+ if (rkvdec_queue_busy(ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE))
+ return -EBUSY;
+ }
+ ctx->sps = new_sps;
+ /*
+ * For the initial SPS setting and when the pixel format is
+ * changed adjust the pixel format stored in the context
+ */
+ pix_mp->pixelformat = rkvdec_get_valid_fmt(ctx);
+ rkvdec_fill_decoded_pixfmt(ctx, pix_mp);
+ }
+
+ return 0;
+}
+
static int rkvdec_try_ctrl(struct v4l2_ctrl *ctrl)
{
struct rkvdec_ctx *ctx = container_of(ctrl->handler, struct rkvdec_ctx, ctrl_hdl);
@@ -104,8 +177,16 @@ static int rkvdec_try_ctrl(struct v4l2_ctrl *ctrl)
return 0;
}
+static int rkvdec_s_ctrl(struct v4l2_ctrl *ctrl)
+{
+ struct rkvdec_ctx *ctx = container_of(ctrl->handler, struct rkvdec_ctx, ctrl_hdl);
+
+ return rkvdec_set_sps(ctx, ctrl);
+}
+
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[] = {
--
2.25.1
Powered by blists - more mailing lists