aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/v4l2-core/v4l2-ioctl.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/v4l2-core/v4l2-ioctl.c')
-rw-r--r--drivers/media/v4l2-core/v4l2-ioctl.c65
1 files changed, 61 insertions, 4 deletions
diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c b/drivers/media/v4l2-core/v4l2-ioctl.c
index 96bc117f66b2..2e630005676f 100644
--- a/drivers/media/v4l2-core/v4l2-ioctl.c
+++ b/drivers/media/v4l2-core/v4l2-ioctl.c
@@ -973,13 +973,48 @@ static int check_fmt(struct file *file, enum v4l2_buf_type type)
973 return -EINVAL; 973 return -EINVAL;
974} 974}
975 975
976static void v4l_sanitize_format(struct v4l2_format *fmt)
977{
978 unsigned int offset;
979
980 /*
981 * The v4l2_pix_format structure has been extended with fields that were
982 * not previously required to be set to zero by applications. The priv
983 * field, when set to a magic value, indicates the the extended fields
984 * are valid. Otherwise they will contain undefined values. To simplify
985 * the API towards drivers zero the extended fields and set the priv
986 * field to the magic value when the extended pixel format structure
987 * isn't used by applications.
988 */
989
990 if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE &&
991 fmt->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
992 return;
993
994 if (fmt->fmt.pix.priv == V4L2_PIX_FMT_PRIV_MAGIC)
995 return;
996
997 fmt->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC;
998
999 offset = offsetof(struct v4l2_pix_format, priv)
1000 + sizeof(fmt->fmt.pix.priv);
1001 memset(((void *)&fmt->fmt.pix) + offset, 0,
1002 sizeof(fmt->fmt.pix) - offset);
1003}
1004
976static int v4l_querycap(const struct v4l2_ioctl_ops *ops, 1005static int v4l_querycap(const struct v4l2_ioctl_ops *ops,
977 struct file *file, void *fh, void *arg) 1006 struct file *file, void *fh, void *arg)
978{ 1007{
979 struct v4l2_capability *cap = (struct v4l2_capability *)arg; 1008 struct v4l2_capability *cap = (struct v4l2_capability *)arg;
1009 int ret;
980 1010
981 cap->version = LINUX_VERSION_CODE; 1011 cap->version = LINUX_VERSION_CODE;
982 return ops->vidioc_querycap(file, fh, cap); 1012
1013 ret = ops->vidioc_querycap(file, fh, cap);
1014
1015 cap->capabilities |= V4L2_CAP_EXT_PIX_FORMAT;
1016
1017 return ret;
983} 1018}
984 1019
985static int v4l_s_input(const struct v4l2_ioctl_ops *ops, 1020static int v4l_s_input(const struct v4l2_ioctl_ops *ops,
@@ -1103,12 +1138,17 @@ static int v4l_g_fmt(const struct v4l2_ioctl_ops *ops,
1103 bool is_sdr = vfd->vfl_type == VFL_TYPE_SDR; 1138 bool is_sdr = vfd->vfl_type == VFL_TYPE_SDR;
1104 bool is_rx = vfd->vfl_dir != VFL_DIR_TX; 1139 bool is_rx = vfd->vfl_dir != VFL_DIR_TX;
1105 bool is_tx = vfd->vfl_dir != VFL_DIR_RX; 1140 bool is_tx = vfd->vfl_dir != VFL_DIR_RX;
1141 int ret;
1142
1143 p->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC;
1106 1144
1107 switch (p->type) { 1145 switch (p->type) {
1108 case V4L2_BUF_TYPE_VIDEO_CAPTURE: 1146 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
1109 if (unlikely(!is_rx || !is_vid || !ops->vidioc_g_fmt_vid_cap)) 1147 if (unlikely(!is_rx || !is_vid || !ops->vidioc_g_fmt_vid_cap))
1110 break; 1148 break;
1111 return ops->vidioc_g_fmt_vid_cap(file, fh, arg); 1149 ret = ops->vidioc_g_fmt_vid_cap(file, fh, arg);
1150 p->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC;
1151 return ret;
1112 case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: 1152 case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
1113 if (unlikely(!is_rx || !is_vid || !ops->vidioc_g_fmt_vid_cap_mplane)) 1153 if (unlikely(!is_rx || !is_vid || !ops->vidioc_g_fmt_vid_cap_mplane))
1114 break; 1154 break;
@@ -1128,7 +1168,9 @@ static int v4l_g_fmt(const struct v4l2_ioctl_ops *ops,
1128 case V4L2_BUF_TYPE_VIDEO_OUTPUT: 1168 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
1129 if (unlikely(!is_tx || !is_vid || !ops->vidioc_g_fmt_vid_out)) 1169 if (unlikely(!is_tx || !is_vid || !ops->vidioc_g_fmt_vid_out))
1130 break; 1170 break;
1131 return ops->vidioc_g_fmt_vid_out(file, fh, arg); 1171 ret = ops->vidioc_g_fmt_vid_out(file, fh, arg);
1172 p->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC;
1173 return ret;
1132 case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: 1174 case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
1133 if (unlikely(!is_tx || !is_vid || !ops->vidioc_g_fmt_vid_out_mplane)) 1175 if (unlikely(!is_tx || !is_vid || !ops->vidioc_g_fmt_vid_out_mplane))
1134 break; 1176 break;
@@ -1163,6 +1205,8 @@ static int v4l_s_fmt(const struct v4l2_ioctl_ops *ops,
1163 bool is_rx = vfd->vfl_dir != VFL_DIR_TX; 1205 bool is_rx = vfd->vfl_dir != VFL_DIR_TX;
1164 bool is_tx = vfd->vfl_dir != VFL_DIR_RX; 1206 bool is_tx = vfd->vfl_dir != VFL_DIR_RX;
1165 1207
1208 v4l_sanitize_format(p);
1209
1166 switch (p->type) { 1210 switch (p->type) {
1167 case V4L2_BUF_TYPE_VIDEO_CAPTURE: 1211 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
1168 if (unlikely(!is_rx || !is_vid || !ops->vidioc_s_fmt_vid_cap)) 1212 if (unlikely(!is_rx || !is_vid || !ops->vidioc_s_fmt_vid_cap))
@@ -1233,6 +1277,8 @@ static int v4l_try_fmt(const struct v4l2_ioctl_ops *ops,
1233 bool is_rx = vfd->vfl_dir != VFL_DIR_TX; 1277 bool is_rx = vfd->vfl_dir != VFL_DIR_TX;
1234 bool is_tx = vfd->vfl_dir != VFL_DIR_RX; 1278 bool is_tx = vfd->vfl_dir != VFL_DIR_RX;
1235 1279
1280 v4l_sanitize_format(p);
1281
1236 switch (p->type) { 1282 switch (p->type) {
1237 case V4L2_BUF_TYPE_VIDEO_CAPTURE: 1283 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
1238 if (unlikely(!is_rx || !is_vid || !ops->vidioc_try_fmt_vid_cap)) 1284 if (unlikely(!is_rx || !is_vid || !ops->vidioc_try_fmt_vid_cap))
@@ -1516,7 +1562,18 @@ static int v4l_create_bufs(const struct v4l2_ioctl_ops *ops,
1516 struct v4l2_create_buffers *create = arg; 1562 struct v4l2_create_buffers *create = arg;
1517 int ret = check_fmt(file, create->format.type); 1563 int ret = check_fmt(file, create->format.type);
1518 1564
1519 return ret ? ret : ops->vidioc_create_bufs(file, fh, create); 1565 if (ret)
1566 return ret;
1567
1568 v4l_sanitize_format(&create->format);
1569
1570 ret = ops->vidioc_create_bufs(file, fh, create);
1571
1572 if (create->format.type == V4L2_BUF_TYPE_VIDEO_CAPTURE ||
1573 create->format.type == V4L2_BUF_TYPE_VIDEO_OUTPUT)
1574 create->format.fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC;
1575
1576 return ret;
1520} 1577}
1521 1578
1522static int v4l_prepare_buf(const struct v4l2_ioctl_ops *ops, 1579static int v4l_prepare_buf(const struct v4l2_ioctl_ops *ops,