diff options
Diffstat (limited to 'drivers/media/v4l2-core/v4l2-ioctl.c')
-rw-r--r-- | drivers/media/v4l2-core/v4l2-ioctl.c | 65 |
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 | ||
976 | static 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 | |||
976 | static int v4l_querycap(const struct v4l2_ioctl_ops *ops, | 1005 | static 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 | ||
985 | static int v4l_s_input(const struct v4l2_ioctl_ops *ops, | 1020 | static 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 | ||
1522 | static int v4l_prepare_buf(const struct v4l2_ioctl_ops *ops, | 1579 | static int v4l_prepare_buf(const struct v4l2_ioctl_ops *ops, |