Commit 48e93b0c authored by Laurent Pinchart's avatar Laurent Pinchart Committed by Mauro Carvalho Chehab

media: v4l2: Sanitize colorspace values in the framework

Extend the format sanitization code in the framework to handle invalid
values for the colorspace-related fields.
Signed-off-by: default avatarLaurent Pinchart <laurent.pinchart@ideasonboard.com>
Acked-by: default avatarSakari Ailus <sakari.ailus@linux.intel.com>
Reviewed-by: default avatarHans Verkuil <hverkuil-cisco@xs4all.nl>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@kernel.org>
parent 718d2153
......@@ -1007,6 +1007,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;
......@@ -1026,20 +1051,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;
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->type != V4L2_BUF_TYPE_VIDEO_CAPTURE &&
fmt->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
return;
if (fmt->fmt.pix.priv == V4L2_PIX_FMT_PRIV_MAGIC)
return;
fmt->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC;
offset = offsetof(struct v4l2_pix_format, priv)
+ sizeof(fmt->fmt.pix.priv);
memset(((void *)&fmt->fmt.pix) + offset, 0,
sizeof(fmt->fmt.pix) - offset);
/* 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;
v4l_sanitize_colorspace(fmt->fmt.pix_mp.pixelformat,
&fmt->fmt.pix_mp.colorspace, &ycbcr_enc,
&quantization, &xfer_func);
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,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment