summaryrefslogtreecommitdiff
path: root/drivers/media/v4l2-core
diff options
context:
space:
mode:
authorLaurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>2016-04-12 19:40:46 -0300
committerMauro Carvalho Chehab <mchehab@s-opensource.com>2017-04-14 22:37:02 -0300
commitfb9ffa6a7f7ef39cc0f14f417b66411be5492512 (patch)
tree5763fa3d455d88c597b49969e04fe2825a0a2a38 /drivers/media/v4l2-core
parent3e9a0e0bfafdf6c28c520d43fd64c5775d04662f (diff)
[media] v4l: Add metadata buffer type and format
The metadata buffer type is used to transfer metadata between userspace and kernelspace through a V4L2 buffers queue. It comes with a new metadata capture capability and format description. Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> Tested-by: Guennadi Liakhovetski <guennadi.liakhovetski@intel.com> Acked-by: Sakari Ailus <sakari.ailus@linux.intel.com> Acked-by: Hans Verkuil <hans.verkuil@cisco.com> [hans.verkuil@cisco.com: removed left-over 'experimental' note] [hans.verkuil@cisco.com: add newline after _v4l2-meta-format label] Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
Diffstat (limited to 'drivers/media/v4l2-core')
-rw-r--r--drivers/media/v4l2-core/v4l2-compat-ioctl32.c19
-rw-r--r--drivers/media/v4l2-core/v4l2-dev.c16
-rw-r--r--drivers/media/v4l2-core/v4l2-ioctl.c34
-rw-r--r--drivers/media/v4l2-core/videobuf2-v4l2.c3
4 files changed, 66 insertions, 6 deletions
diff --git a/drivers/media/v4l2-core/v4l2-compat-ioctl32.c b/drivers/media/v4l2-core/v4l2-compat-ioctl32.c
index 77b8a2dcfcdf..6f52970f8b54 100644
--- a/drivers/media/v4l2-core/v4l2-compat-ioctl32.c
+++ b/drivers/media/v4l2-core/v4l2-compat-ioctl32.c
@@ -161,6 +161,20 @@ static inline int put_v4l2_sdr_format(struct v4l2_sdr_format *kp, struct v4l2_sd
return 0;
}
+static inline int get_v4l2_meta_format(struct v4l2_meta_format *kp, struct v4l2_meta_format __user *up)
+{
+ if (copy_from_user(kp, up, sizeof(struct v4l2_meta_format)))
+ return -EFAULT;
+ return 0;
+}
+
+static inline int put_v4l2_meta_format(struct v4l2_meta_format *kp, struct v4l2_meta_format __user *up)
+{
+ if (copy_to_user(up, kp, sizeof(struct v4l2_meta_format)))
+ return -EFAULT;
+ return 0;
+}
+
struct v4l2_format32 {
__u32 type; /* enum v4l2_buf_type */
union {
@@ -170,6 +184,7 @@ struct v4l2_format32 {
struct v4l2_vbi_format vbi;
struct v4l2_sliced_vbi_format sliced;
struct v4l2_sdr_format sdr;
+ struct v4l2_meta_format meta;
__u8 raw_data[200]; /* user-defined */
} fmt;
};
@@ -216,6 +231,8 @@ static int __get_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __us
case V4L2_BUF_TYPE_SDR_CAPTURE:
case V4L2_BUF_TYPE_SDR_OUTPUT:
return get_v4l2_sdr_format(&kp->fmt.sdr, &up->fmt.sdr);
+ case V4L2_BUF_TYPE_META_CAPTURE:
+ return get_v4l2_meta_format(&kp->fmt.meta, &up->fmt.meta);
default:
pr_info("compat_ioctl32: unexpected VIDIOC_FMT type %d\n",
kp->type);
@@ -263,6 +280,8 @@ static int __put_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __us
case V4L2_BUF_TYPE_SDR_CAPTURE:
case V4L2_BUF_TYPE_SDR_OUTPUT:
return put_v4l2_sdr_format(&kp->fmt.sdr, &up->fmt.sdr);
+ case V4L2_BUF_TYPE_META_CAPTURE:
+ return put_v4l2_meta_format(&kp->fmt.meta, &up->fmt.meta);
default:
pr_info("compat_ioctl32: unexpected VIDIOC_FMT type %d\n",
kp->type);
diff --git a/drivers/media/v4l2-core/v4l2-dev.c b/drivers/media/v4l2-core/v4l2-dev.c
index fa2124cb31bd..c647ba648805 100644
--- a/drivers/media/v4l2-core/v4l2-dev.c
+++ b/drivers/media/v4l2-core/v4l2-dev.c
@@ -575,30 +575,34 @@ static void determine_valid_ioctls(struct video_device *vdev)
set_bit(_IOC_NR(VIDIOC_ENUM_FREQ_BANDS), valid_ioctls);
if (is_vid || is_tch) {
- /* video specific ioctls */
+ /* video and metadata specific ioctls */
if ((is_rx && (ops->vidioc_enum_fmt_vid_cap ||
ops->vidioc_enum_fmt_vid_cap_mplane ||
- ops->vidioc_enum_fmt_vid_overlay)) ||
+ ops->vidioc_enum_fmt_vid_overlay ||
+ ops->vidioc_enum_fmt_meta_cap)) ||
(is_tx && (ops->vidioc_enum_fmt_vid_out ||
ops->vidioc_enum_fmt_vid_out_mplane)))
set_bit(_IOC_NR(VIDIOC_ENUM_FMT), valid_ioctls);
if ((is_rx && (ops->vidioc_g_fmt_vid_cap ||
ops->vidioc_g_fmt_vid_cap_mplane ||
- ops->vidioc_g_fmt_vid_overlay)) ||
+ ops->vidioc_g_fmt_vid_overlay ||
+ ops->vidioc_g_fmt_meta_cap)) ||
(is_tx && (ops->vidioc_g_fmt_vid_out ||
ops->vidioc_g_fmt_vid_out_mplane ||
ops->vidioc_g_fmt_vid_out_overlay)))
set_bit(_IOC_NR(VIDIOC_G_FMT), valid_ioctls);
if ((is_rx && (ops->vidioc_s_fmt_vid_cap ||
ops->vidioc_s_fmt_vid_cap_mplane ||
- ops->vidioc_s_fmt_vid_overlay)) ||
+ ops->vidioc_s_fmt_vid_overlay ||
+ ops->vidioc_s_fmt_meta_cap)) ||
(is_tx && (ops->vidioc_s_fmt_vid_out ||
ops->vidioc_s_fmt_vid_out_mplane ||
ops->vidioc_s_fmt_vid_out_overlay)))
set_bit(_IOC_NR(VIDIOC_S_FMT), valid_ioctls);
if ((is_rx && (ops->vidioc_try_fmt_vid_cap ||
ops->vidioc_try_fmt_vid_cap_mplane ||
- ops->vidioc_try_fmt_vid_overlay)) ||
+ ops->vidioc_try_fmt_vid_overlay ||
+ ops->vidioc_try_fmt_meta_cap)) ||
(is_tx && (ops->vidioc_try_fmt_vid_out ||
ops->vidioc_try_fmt_vid_out_mplane ||
ops->vidioc_try_fmt_vid_out_overlay)))
@@ -664,7 +668,7 @@ static void determine_valid_ioctls(struct video_device *vdev)
}
if (is_vid || is_vbi || is_sdr || is_tch) {
- /* ioctls valid for video, vbi or sdr */
+ /* ioctls valid for video, metadata, vbi or sdr */
SET_VALID_IOCTL(ops, VIDIOC_REQBUFS, vidioc_reqbufs);
SET_VALID_IOCTL(ops, VIDIOC_QUERYBUF, vidioc_querybuf);
SET_VALID_IOCTL(ops, VIDIOC_QBUF, vidioc_qbuf);
diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c b/drivers/media/v4l2-core/v4l2-ioctl.c
index 93e8f42b0d63..dec6b120a5a2 100644
--- a/drivers/media/v4l2-core/v4l2-ioctl.c
+++ b/drivers/media/v4l2-core/v4l2-ioctl.c
@@ -155,6 +155,7 @@ const char *v4l2_type_names[] = {
[V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE] = "vid-out-mplane",
[V4L2_BUF_TYPE_SDR_CAPTURE] = "sdr-cap",
[V4L2_BUF_TYPE_SDR_OUTPUT] = "sdr-out",
+ [V4L2_BUF_TYPE_META_CAPTURE] = "meta-cap",
};
EXPORT_SYMBOL(v4l2_type_names);
@@ -246,6 +247,7 @@ static void v4l_print_format(const void *arg, bool write_only)
const struct v4l2_sliced_vbi_format *sliced;
const struct v4l2_window *win;
const struct v4l2_sdr_format *sdr;
+ const struct v4l2_meta_format *meta;
unsigned i;
pr_cont("type=%s", prt_names(p->type, v4l2_type_names));
@@ -325,6 +327,15 @@ static void v4l_print_format(const void *arg, bool write_only)
(sdr->pixelformat >> 16) & 0xff,
(sdr->pixelformat >> 24) & 0xff);
break;
+ case V4L2_BUF_TYPE_META_CAPTURE:
+ meta = &p->fmt.meta;
+ pr_cont(", dataformat=%c%c%c%c, buffersize=%u\n",
+ (meta->dataformat >> 0) & 0xff,
+ (meta->dataformat >> 8) & 0xff,
+ (meta->dataformat >> 16) & 0xff,
+ (meta->dataformat >> 24) & 0xff,
+ meta->buffersize);
+ break;
}
}
@@ -943,6 +954,10 @@ static int check_fmt(struct file *file, enum v4l2_buf_type type)
if (is_sdr && is_tx && ops->vidioc_g_fmt_sdr_out)
return 0;
break;
+ case V4L2_BUF_TYPE_META_CAPTURE:
+ if (is_vid && is_rx && ops->vidioc_g_fmt_meta_cap)
+ return 0;
+ break;
default:
break;
}
@@ -1327,6 +1342,11 @@ static int v4l_enum_fmt(const struct v4l2_ioctl_ops *ops,
break;
ret = ops->vidioc_enum_fmt_sdr_out(file, fh, arg);
break;
+ case V4L2_BUF_TYPE_META_CAPTURE:
+ if (unlikely(!is_rx || !is_vid || !ops->vidioc_enum_fmt_meta_cap))
+ break;
+ ret = ops->vidioc_enum_fmt_meta_cap(file, fh, arg);
+ break;
}
if (ret == 0)
v4l_fill_fmtdesc(p);
@@ -1426,6 +1446,10 @@ static int v4l_g_fmt(const struct v4l2_ioctl_ops *ops,
if (unlikely(!is_tx || !is_sdr || !ops->vidioc_g_fmt_sdr_out))
break;
return ops->vidioc_g_fmt_sdr_out(file, fh, arg);
+ case V4L2_BUF_TYPE_META_CAPTURE:
+ if (unlikely(!is_rx || !is_vid || !ops->vidioc_g_fmt_meta_cap))
+ break;
+ return ops->vidioc_g_fmt_meta_cap(file, fh, arg);
}
return -EINVAL;
}
@@ -1531,6 +1555,11 @@ static int v4l_s_fmt(const struct v4l2_ioctl_ops *ops,
break;
CLEAR_AFTER_FIELD(p, fmt.sdr);
return ops->vidioc_s_fmt_sdr_out(file, fh, arg);
+ case V4L2_BUF_TYPE_META_CAPTURE:
+ if (unlikely(!is_rx || !is_vid || !ops->vidioc_s_fmt_meta_cap))
+ break;
+ CLEAR_AFTER_FIELD(p, fmt.meta);
+ return ops->vidioc_s_fmt_meta_cap(file, fh, arg);
}
return -EINVAL;
}
@@ -1616,6 +1645,11 @@ static int v4l_try_fmt(const struct v4l2_ioctl_ops *ops,
break;
CLEAR_AFTER_FIELD(p, fmt.sdr);
return ops->vidioc_try_fmt_sdr_out(file, fh, arg);
+ case V4L2_BUF_TYPE_META_CAPTURE:
+ if (unlikely(!is_rx || !is_vid || !ops->vidioc_try_fmt_meta_cap))
+ break;
+ CLEAR_AFTER_FIELD(p, fmt.meta);
+ return ops->vidioc_try_fmt_meta_cap(file, fh, arg);
}
return -EINVAL;
}
diff --git a/drivers/media/v4l2-core/videobuf2-v4l2.c b/drivers/media/v4l2-core/videobuf2-v4l2.c
index 3529849d2218..0c0669976bdc 100644
--- a/drivers/media/v4l2-core/videobuf2-v4l2.c
+++ b/drivers/media/v4l2-core/videobuf2-v4l2.c
@@ -544,6 +544,9 @@ int vb2_create_bufs(struct vb2_queue *q, struct v4l2_create_buffers *create)
case V4L2_BUF_TYPE_SDR_OUTPUT:
requested_sizes[0] = f->fmt.sdr.buffersize;
break;
+ case V4L2_BUF_TYPE_META_CAPTURE:
+ requested_sizes[0] = f->fmt.meta.buffersize;
+ break;
default:
return -EINVAL;
}