From patchwork Thu Jun 16 18:23:48 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 16253 Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id C2A0FC3276 for ; Thu, 16 Jun 2022 18:24:15 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id F2F0A65645; Thu, 16 Jun 2022 20:24:14 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1655403855; bh=bWNlCtgrMVPV7UjDm0QpNxf3zyYr7EaxNscRNaxH4jw=; h=To:Date:In-Reply-To:References:Subject:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc: From; b=bW6SuRFyBplRjYKZW5ayFc/i1ZVF18wZcYN0w1EYxlTpJ6ppHkohr3RkB8FY+qNUd gXcc08+6otWr0iuIGP49K14toeFVZQxWv9dQaFpKwqOH6ZUQ+LUnFz24fewKYuq4CA LoAZIfiz5puB3AxDnFRN44y0VNw8Ge7gXE9AzkAhiW1jhw/VVizyvsJlJ3sYoqIpBc UFHVLi4izBYdyBADviHEZQ5VMYcY1sknLAI5ge/HepvNbGBaA2133dQm42RvDg4X8Y Fpt0BJmONygQn45eGehrurdgZQLRXIV+olHtF77+qR9jASAb1YDjqkdeAFmtxW6BCH yJFrn4bL1RDsA== Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id F28DC600F0 for ; Thu, 16 Jun 2022 20:24:09 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="vJMHmKCD"; dkim-atps=neutral Received: from pendragon.lan (62-78-145-57.bb.dnainternet.fi [62.78.145.57]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 3AF3ABC0; Thu, 16 Jun 2022 20:24:09 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1655403849; bh=bWNlCtgrMVPV7UjDm0QpNxf3zyYr7EaxNscRNaxH4jw=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=vJMHmKCDQNT99G/rz6gEGI4ajhlaDWhmCPRup+swIpKaHw5kvaFdhWt+66/zo2Hjt AkY3Pg4kN/4x0FxL4Sy03tgbJBGn4cw6TTFO2j/3MxbHtMJmffsr2FA9xwhNu/UFfk lOdjCMPlLW0ok+M4sunCVqmJa2yjTai7fvBZPxCQ= To: libcamera-devel@lists.libcamera.org Date: Thu, 16 Jun 2022 21:23:48 +0300 Message-Id: <20220616182350.17352-6-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220616182350.17352-1-laurent.pinchart@ideasonboard.com> References: <20220616182350.17352-1-laurent.pinchart@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 5/7] media: v4l2: Sanitize colorspace values in the framework X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Laurent Pinchart via libcamera-devel From: Laurent Pinchart Reply-To: Laurent Pinchart Cc: Sakari Ailus , linux-imx@nxp.com, kernel@pengutronix.de, Hans Verkuil Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" Extend the format sanitization code in the framework to handle invalid values for the colorspace-related fields. Signed-off-by: Laurent Pinchart Acked-by: Sakari Ailus --- drivers/media/v4l2-core/v4l2-ioctl.c | 65 +++++++++++++++++++++++----- 1 file changed, 55 insertions(+), 10 deletions(-) diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c b/drivers/media/v4l2-core/v4l2-ioctl.c index 18ed2227255a..24b5968e8f32 100644 --- a/drivers/media/v4l2-core/v4l2-ioctl.c +++ b/drivers/media/v4l2-core/v4l2-ioctl.c @@ -1008,6 +1008,31 @@ static int check_fmt(struct file *file, enum v4l2_buf_type type) return -EINVAL; } +static void v4l_sanitize_colorspace(u32 pixelformat, u32 *colorspace, + u32 *encoding, u32 *quantization, + u32 *xfer_func) +{ + bool is_hsv = pixelformat == V4L2_PIX_FMT_HSV24 || + pixelformat == V4L2_PIX_FMT_HSV32; + + if (!v4l2_is_colorspace_valid(*colorspace)) { + *colorspace = V4L2_COLORSPACE_DEFAULT; + *encoding = V4L2_YCBCR_ENC_DEFAULT; + *quantization = V4L2_QUANTIZATION_DEFAULT; + *xfer_func = V4L2_XFER_FUNC_DEFAULT; + } + + if ((!is_hsv && !v4l2_is_ycbcr_enc_valid(*encoding)) || + (is_hsv && !v4l2_is_hsv_enc_valid(*encoding))) + *encoding = V4L2_YCBCR_ENC_DEFAULT; + + if (!v4l2_is_quant_valid(*quantization)) + *quantization = V4L2_QUANTIZATION_DEFAULT; + + if (!v4l2_is_xfer_func_valid(*xfer_func)) + *xfer_func = V4L2_XFER_FUNC_DEFAULT; +} + static void v4l_sanitize_format(struct v4l2_format *fmt) { unsigned int offset; @@ -1027,20 +1052,40 @@ static void v4l_sanitize_format(struct v4l2_format *fmt) * field to the magic value when the extended pixel format structure * isn't used by applications. */ + if (fmt->type == V4L2_BUF_TYPE_VIDEO_CAPTURE || + fmt->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) { + if (fmt->fmt.pix.priv != V4L2_PIX_FMT_PRIV_MAGIC) { + fmt->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC; - if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE && - fmt->type != V4L2_BUF_TYPE_VIDEO_OUTPUT) - return; + offset = offsetof(struct v4l2_pix_format, priv) + + sizeof(fmt->fmt.pix.priv); + memset(((void *)&fmt->fmt.pix) + offset, 0, + sizeof(fmt->fmt.pix) - offset); + } + } - if (fmt->fmt.pix.priv == V4L2_PIX_FMT_PRIV_MAGIC) - return; + /* Replace invalid colorspace values with defaults. */ + if (fmt->type == V4L2_BUF_TYPE_VIDEO_CAPTURE || + fmt->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) { + v4l_sanitize_colorspace(fmt->fmt.pix.pixelformat, + &fmt->fmt.pix.colorspace, + &fmt->fmt.pix.ycbcr_enc, + &fmt->fmt.pix.quantization, + &fmt->fmt.pix.xfer_func); + } else if (fmt->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE || + fmt->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { + u32 ycbcr_enc = fmt->fmt.pix_mp.ycbcr_enc; + u32 quantization = fmt->fmt.pix_mp.quantization; + u32 xfer_func = fmt->fmt.pix_mp.xfer_func; - fmt->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC; + v4l_sanitize_colorspace(fmt->fmt.pix_mp.pixelformat, + &fmt->fmt.pix_mp.colorspace, &ycbcr_enc, + &quantization, &xfer_func); - offset = offsetof(struct v4l2_pix_format, priv) - + sizeof(fmt->fmt.pix.priv); - memset(((void *)&fmt->fmt.pix) + offset, 0, - sizeof(fmt->fmt.pix) - offset); + fmt->fmt.pix_mp.ycbcr_enc = ycbcr_enc; + fmt->fmt.pix_mp.quantization = quantization; + fmt->fmt.pix_mp.xfer_func = xfer_func; + } } static int v4l_querycap(const struct v4l2_ioctl_ops *ops,