Commit 72148d1a authored by Sakari Ailus's avatar Sakari Ailus Committed by Mauro Carvalho Chehab

media: v4l: Add support for V4L2_BUF_TYPE_META_OUTPUT

The V4L2_BUF_TYPE_META_OUTPUT mirrors the V4L2_BUF_TYPE_META_CAPTURE with
the exception that it is an OUTPUT type. The use case for this is to pass
buffers to the device that are not image data but metadata. The formats,
just as the metadata capture formats, are typically device specific and
highly structured.
Signed-off-by: default avatarSakari Ailus <sakari.ailus@linux.intel.com>
Acked-by: default avatarHans Verkuil <hans.verkuil@cisco.com>
Reviewed-by: default avatarTomasz Figa <tfiga@chromium.org>
Tested-by: default avatarTian Shu Qiu <tian.shu.qiu@intel.com>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab+samsung@kernel.org>
parent fa09d065
...@@ -704,6 +704,7 @@ int vb2_create_bufs(struct vb2_queue *q, struct v4l2_create_buffers *create) ...@@ -704,6 +704,7 @@ int vb2_create_bufs(struct vb2_queue *q, struct v4l2_create_buffers *create)
requested_sizes[0] = f->fmt.sdr.buffersize; requested_sizes[0] = f->fmt.sdr.buffersize;
break; break;
case V4L2_BUF_TYPE_META_CAPTURE: case V4L2_BUF_TYPE_META_CAPTURE:
case V4L2_BUF_TYPE_META_OUTPUT:
requested_sizes[0] = f->fmt.meta.buffersize; requested_sizes[0] = f->fmt.meta.buffersize;
break; break;
default: default:
......
...@@ -323,6 +323,7 @@ static int __get_v4l2_format32(struct v4l2_format __user *p64, ...@@ -323,6 +323,7 @@ static int __get_v4l2_format32(struct v4l2_format __user *p64,
return copy_in_user(&p64->fmt.sdr, &p32->fmt.sdr, return copy_in_user(&p64->fmt.sdr, &p32->fmt.sdr,
sizeof(p64->fmt.sdr)) ? -EFAULT : 0; sizeof(p64->fmt.sdr)) ? -EFAULT : 0;
case V4L2_BUF_TYPE_META_CAPTURE: case V4L2_BUF_TYPE_META_CAPTURE:
case V4L2_BUF_TYPE_META_OUTPUT:
return copy_in_user(&p64->fmt.meta, &p32->fmt.meta, return copy_in_user(&p64->fmt.meta, &p32->fmt.meta,
sizeof(p64->fmt.meta)) ? -EFAULT : 0; sizeof(p64->fmt.meta)) ? -EFAULT : 0;
default: default:
...@@ -392,6 +393,7 @@ static int __put_v4l2_format32(struct v4l2_format __user *p64, ...@@ -392,6 +393,7 @@ static int __put_v4l2_format32(struct v4l2_format __user *p64,
return copy_in_user(&p32->fmt.sdr, &p64->fmt.sdr, return copy_in_user(&p32->fmt.sdr, &p64->fmt.sdr,
sizeof(p64->fmt.sdr)) ? -EFAULT : 0; sizeof(p64->fmt.sdr)) ? -EFAULT : 0;
case V4L2_BUF_TYPE_META_CAPTURE: case V4L2_BUF_TYPE_META_CAPTURE:
case V4L2_BUF_TYPE_META_OUTPUT:
return copy_in_user(&p32->fmt.meta, &p64->fmt.meta, return copy_in_user(&p32->fmt.meta, &p64->fmt.meta,
sizeof(p64->fmt.meta)) ? -EFAULT : 0; sizeof(p64->fmt.meta)) ? -EFAULT : 0;
default: default:
......
...@@ -597,7 +597,8 @@ static void determine_valid_ioctls(struct video_device *vdev) ...@@ -597,7 +597,8 @@ static void determine_valid_ioctls(struct video_device *vdev)
ops->vidioc_enum_fmt_vid_overlay || ops->vidioc_enum_fmt_vid_overlay ||
ops->vidioc_enum_fmt_meta_cap)) || ops->vidioc_enum_fmt_meta_cap)) ||
(is_tx && (ops->vidioc_enum_fmt_vid_out || (is_tx && (ops->vidioc_enum_fmt_vid_out ||
ops->vidioc_enum_fmt_vid_out_mplane))) ops->vidioc_enum_fmt_vid_out_mplane ||
ops->vidioc_enum_fmt_meta_out)))
set_bit(_IOC_NR(VIDIOC_ENUM_FMT), valid_ioctls); set_bit(_IOC_NR(VIDIOC_ENUM_FMT), valid_ioctls);
if ((is_rx && (ops->vidioc_g_fmt_vid_cap || if ((is_rx && (ops->vidioc_g_fmt_vid_cap ||
ops->vidioc_g_fmt_vid_cap_mplane || ops->vidioc_g_fmt_vid_cap_mplane ||
...@@ -605,7 +606,8 @@ static void determine_valid_ioctls(struct video_device *vdev) ...@@ -605,7 +606,8 @@ static void determine_valid_ioctls(struct video_device *vdev)
ops->vidioc_g_fmt_meta_cap)) || ops->vidioc_g_fmt_meta_cap)) ||
(is_tx && (ops->vidioc_g_fmt_vid_out || (is_tx && (ops->vidioc_g_fmt_vid_out ||
ops->vidioc_g_fmt_vid_out_mplane || ops->vidioc_g_fmt_vid_out_mplane ||
ops->vidioc_g_fmt_vid_out_overlay))) ops->vidioc_g_fmt_vid_out_overlay ||
ops->vidioc_g_fmt_meta_out)))
set_bit(_IOC_NR(VIDIOC_G_FMT), valid_ioctls); set_bit(_IOC_NR(VIDIOC_G_FMT), valid_ioctls);
if ((is_rx && (ops->vidioc_s_fmt_vid_cap || if ((is_rx && (ops->vidioc_s_fmt_vid_cap ||
ops->vidioc_s_fmt_vid_cap_mplane || ops->vidioc_s_fmt_vid_cap_mplane ||
...@@ -613,7 +615,8 @@ static void determine_valid_ioctls(struct video_device *vdev) ...@@ -613,7 +615,8 @@ static void determine_valid_ioctls(struct video_device *vdev)
ops->vidioc_s_fmt_meta_cap)) || ops->vidioc_s_fmt_meta_cap)) ||
(is_tx && (ops->vidioc_s_fmt_vid_out || (is_tx && (ops->vidioc_s_fmt_vid_out ||
ops->vidioc_s_fmt_vid_out_mplane || ops->vidioc_s_fmt_vid_out_mplane ||
ops->vidioc_s_fmt_vid_out_overlay))) ops->vidioc_s_fmt_vid_out_overlay ||
ops->vidioc_s_fmt_meta_out)))
set_bit(_IOC_NR(VIDIOC_S_FMT), valid_ioctls); set_bit(_IOC_NR(VIDIOC_S_FMT), valid_ioctls);
if ((is_rx && (ops->vidioc_try_fmt_vid_cap || if ((is_rx && (ops->vidioc_try_fmt_vid_cap ||
ops->vidioc_try_fmt_vid_cap_mplane || ops->vidioc_try_fmt_vid_cap_mplane ||
...@@ -621,7 +624,8 @@ static void determine_valid_ioctls(struct video_device *vdev) ...@@ -621,7 +624,8 @@ static void determine_valid_ioctls(struct video_device *vdev)
ops->vidioc_try_fmt_meta_cap)) || ops->vidioc_try_fmt_meta_cap)) ||
(is_tx && (ops->vidioc_try_fmt_vid_out || (is_tx && (ops->vidioc_try_fmt_vid_out ||
ops->vidioc_try_fmt_vid_out_mplane || ops->vidioc_try_fmt_vid_out_mplane ||
ops->vidioc_try_fmt_vid_out_overlay))) ops->vidioc_try_fmt_vid_out_overlay ||
ops->vidioc_try_fmt_meta_out)))
set_bit(_IOC_NR(VIDIOC_TRY_FMT), valid_ioctls); set_bit(_IOC_NR(VIDIOC_TRY_FMT), valid_ioctls);
SET_VALID_IOCTL(ops, VIDIOC_OVERLAY, vidioc_overlay); SET_VALID_IOCTL(ops, VIDIOC_OVERLAY, vidioc_overlay);
SET_VALID_IOCTL(ops, VIDIOC_G_FBUF, vidioc_g_fbuf); SET_VALID_IOCTL(ops, VIDIOC_G_FBUF, vidioc_g_fbuf);
......
...@@ -194,6 +194,7 @@ const char *v4l2_type_names[] = { ...@@ -194,6 +194,7 @@ const char *v4l2_type_names[] = {
[V4L2_BUF_TYPE_SDR_CAPTURE] = "sdr-cap", [V4L2_BUF_TYPE_SDR_CAPTURE] = "sdr-cap",
[V4L2_BUF_TYPE_SDR_OUTPUT] = "sdr-out", [V4L2_BUF_TYPE_SDR_OUTPUT] = "sdr-out",
[V4L2_BUF_TYPE_META_CAPTURE] = "meta-cap", [V4L2_BUF_TYPE_META_CAPTURE] = "meta-cap",
[V4L2_BUF_TYPE_META_OUTPUT] = "meta-out",
}; };
EXPORT_SYMBOL(v4l2_type_names); EXPORT_SYMBOL(v4l2_type_names);
...@@ -366,6 +367,7 @@ static void v4l_print_format(const void *arg, bool write_only) ...@@ -366,6 +367,7 @@ static void v4l_print_format(const void *arg, bool write_only)
(sdr->pixelformat >> 24) & 0xff); (sdr->pixelformat >> 24) & 0xff);
break; break;
case V4L2_BUF_TYPE_META_CAPTURE: case V4L2_BUF_TYPE_META_CAPTURE:
case V4L2_BUF_TYPE_META_OUTPUT:
meta = &p->fmt.meta; meta = &p->fmt.meta;
pr_cont(", dataformat=%c%c%c%c, buffersize=%u\n", pr_cont(", dataformat=%c%c%c%c, buffersize=%u\n",
(meta->dataformat >> 0) & 0xff, (meta->dataformat >> 0) & 0xff,
...@@ -999,6 +1001,10 @@ static int check_fmt(struct file *file, enum v4l2_buf_type type) ...@@ -999,6 +1001,10 @@ static int check_fmt(struct file *file, enum v4l2_buf_type type)
if (is_vid && is_rx && ops->vidioc_g_fmt_meta_cap) if (is_vid && is_rx && ops->vidioc_g_fmt_meta_cap)
return 0; return 0;
break; break;
case V4L2_BUF_TYPE_META_OUTPUT:
if (is_vid && is_tx && ops->vidioc_g_fmt_meta_out)
return 0;
break;
default: default:
break; break;
} }
...@@ -1410,6 +1416,11 @@ static int v4l_enum_fmt(const struct v4l2_ioctl_ops *ops, ...@@ -1410,6 +1416,11 @@ static int v4l_enum_fmt(const struct v4l2_ioctl_ops *ops,
break; break;
ret = ops->vidioc_enum_fmt_meta_cap(file, fh, arg); ret = ops->vidioc_enum_fmt_meta_cap(file, fh, arg);
break; break;
case V4L2_BUF_TYPE_META_OUTPUT:
if (unlikely(!ops->vidioc_enum_fmt_meta_out))
break;
ret = ops->vidioc_enum_fmt_meta_out(file, fh, arg);
break;
} }
if (ret == 0) if (ret == 0)
v4l_fill_fmtdesc(p); v4l_fill_fmtdesc(p);
...@@ -1488,6 +1499,8 @@ static int v4l_g_fmt(const struct v4l2_ioctl_ops *ops, ...@@ -1488,6 +1499,8 @@ static int v4l_g_fmt(const struct v4l2_ioctl_ops *ops,
return ops->vidioc_g_fmt_sdr_out(file, fh, arg); return ops->vidioc_g_fmt_sdr_out(file, fh, arg);
case V4L2_BUF_TYPE_META_CAPTURE: case V4L2_BUF_TYPE_META_CAPTURE:
return ops->vidioc_g_fmt_meta_cap(file, fh, arg); return ops->vidioc_g_fmt_meta_cap(file, fh, arg);
case V4L2_BUF_TYPE_META_OUTPUT:
return ops->vidioc_g_fmt_meta_out(file, fh, arg);
} }
return -EINVAL; return -EINVAL;
} }
...@@ -1601,6 +1614,11 @@ static int v4l_s_fmt(const struct v4l2_ioctl_ops *ops, ...@@ -1601,6 +1614,11 @@ static int v4l_s_fmt(const struct v4l2_ioctl_ops *ops,
break; break;
CLEAR_AFTER_FIELD(p, fmt.meta); CLEAR_AFTER_FIELD(p, fmt.meta);
return ops->vidioc_s_fmt_meta_cap(file, fh, arg); return ops->vidioc_s_fmt_meta_cap(file, fh, arg);
case V4L2_BUF_TYPE_META_OUTPUT:
if (unlikely(!ops->vidioc_s_fmt_meta_out))
break;
CLEAR_AFTER_FIELD(p, fmt.meta);
return ops->vidioc_s_fmt_meta_out(file, fh, arg);
} }
return -EINVAL; return -EINVAL;
} }
...@@ -1693,6 +1711,11 @@ static int v4l_try_fmt(const struct v4l2_ioctl_ops *ops, ...@@ -1693,6 +1711,11 @@ static int v4l_try_fmt(const struct v4l2_ioctl_ops *ops,
break; break;
CLEAR_AFTER_FIELD(p, fmt.meta); CLEAR_AFTER_FIELD(p, fmt.meta);
return ops->vidioc_try_fmt_meta_cap(file, fh, arg); return ops->vidioc_try_fmt_meta_cap(file, fh, arg);
case V4L2_BUF_TYPE_META_OUTPUT:
if (unlikely(!ops->vidioc_try_fmt_meta_out))
break;
CLEAR_AFTER_FIELD(p, fmt.meta);
return ops->vidioc_try_fmt_meta_out(file, fh, arg);
} }
return -EINVAL; return -EINVAL;
} }
......
...@@ -48,6 +48,9 @@ struct v4l2_fh; ...@@ -48,6 +48,9 @@ struct v4l2_fh;
* @vidioc_enum_fmt_meta_cap: pointer to the function that implements * @vidioc_enum_fmt_meta_cap: pointer to the function that implements
* :ref:`VIDIOC_ENUM_FMT <vidioc_enum_fmt>` ioctl logic * :ref:`VIDIOC_ENUM_FMT <vidioc_enum_fmt>` ioctl logic
* for metadata capture * for metadata capture
* @vidioc_enum_fmt_meta_out: pointer to the function that implements
* :ref:`VIDIOC_ENUM_FMT <vidioc_enum_fmt>` ioctl logic
* for metadata output
* @vidioc_g_fmt_vid_cap: pointer to the function that implements * @vidioc_g_fmt_vid_cap: pointer to the function that implements
* :ref:`VIDIOC_G_FMT <vidioc_g_fmt>` ioctl logic for video capture * :ref:`VIDIOC_G_FMT <vidioc_g_fmt>` ioctl logic for video capture
* in single plane mode * in single plane mode
...@@ -80,6 +83,8 @@ struct v4l2_fh; ...@@ -80,6 +83,8 @@ struct v4l2_fh;
* Radio output * Radio output
* @vidioc_g_fmt_meta_cap: pointer to the function that implements * @vidioc_g_fmt_meta_cap: pointer to the function that implements
* :ref:`VIDIOC_G_FMT <vidioc_g_fmt>` ioctl logic for metadata capture * :ref:`VIDIOC_G_FMT <vidioc_g_fmt>` ioctl logic for metadata capture
* @vidioc_g_fmt_meta_out: pointer to the function that implements
* :ref:`VIDIOC_G_FMT <vidioc_g_fmt>` ioctl logic for metadata output
* @vidioc_s_fmt_vid_cap: pointer to the function that implements * @vidioc_s_fmt_vid_cap: pointer to the function that implements
* :ref:`VIDIOC_S_FMT <vidioc_g_fmt>` ioctl logic for video capture * :ref:`VIDIOC_S_FMT <vidioc_g_fmt>` ioctl logic for video capture
* in single plane mode * in single plane mode
...@@ -112,6 +117,8 @@ struct v4l2_fh; ...@@ -112,6 +117,8 @@ struct v4l2_fh;
* Radio output * Radio output
* @vidioc_s_fmt_meta_cap: pointer to the function that implements * @vidioc_s_fmt_meta_cap: pointer to the function that implements
* :ref:`VIDIOC_S_FMT <vidioc_g_fmt>` ioctl logic for metadata capture * :ref:`VIDIOC_S_FMT <vidioc_g_fmt>` ioctl logic for metadata capture
* @vidioc_s_fmt_meta_out: pointer to the function that implements
* :ref:`VIDIOC_S_FMT <vidioc_g_fmt>` ioctl logic for metadata output
* @vidioc_try_fmt_vid_cap: pointer to the function that implements * @vidioc_try_fmt_vid_cap: pointer to the function that implements
* :ref:`VIDIOC_TRY_FMT <vidioc_g_fmt>` ioctl logic for video capture * :ref:`VIDIOC_TRY_FMT <vidioc_g_fmt>` ioctl logic for video capture
* in single plane mode * in single plane mode
...@@ -146,6 +153,8 @@ struct v4l2_fh; ...@@ -146,6 +153,8 @@ struct v4l2_fh;
* Radio output * Radio output
* @vidioc_try_fmt_meta_cap: pointer to the function that implements * @vidioc_try_fmt_meta_cap: pointer to the function that implements
* :ref:`VIDIOC_TRY_FMT <vidioc_g_fmt>` ioctl logic for metadata capture * :ref:`VIDIOC_TRY_FMT <vidioc_g_fmt>` ioctl logic for metadata capture
* @vidioc_try_fmt_meta_out: pointer to the function that implements
* :ref:`VIDIOC_TRY_FMT <vidioc_g_fmt>` ioctl logic for metadata output
* @vidioc_reqbufs: pointer to the function that implements * @vidioc_reqbufs: pointer to the function that implements
* :ref:`VIDIOC_REQBUFS <vidioc_reqbufs>` ioctl * :ref:`VIDIOC_REQBUFS <vidioc_reqbufs>` ioctl
* @vidioc_querybuf: pointer to the function that implements * @vidioc_querybuf: pointer to the function that implements
...@@ -314,6 +323,8 @@ struct v4l2_ioctl_ops { ...@@ -314,6 +323,8 @@ struct v4l2_ioctl_ops {
struct v4l2_fmtdesc *f); struct v4l2_fmtdesc *f);
int (*vidioc_enum_fmt_meta_cap)(struct file *file, void *fh, int (*vidioc_enum_fmt_meta_cap)(struct file *file, void *fh,
struct v4l2_fmtdesc *f); struct v4l2_fmtdesc *f);
int (*vidioc_enum_fmt_meta_out)(struct file *file, void *fh,
struct v4l2_fmtdesc *f);
/* VIDIOC_G_FMT handlers */ /* VIDIOC_G_FMT handlers */
int (*vidioc_g_fmt_vid_cap)(struct file *file, void *fh, int (*vidioc_g_fmt_vid_cap)(struct file *file, void *fh,
...@@ -342,6 +353,8 @@ struct v4l2_ioctl_ops { ...@@ -342,6 +353,8 @@ struct v4l2_ioctl_ops {
struct v4l2_format *f); struct v4l2_format *f);
int (*vidioc_g_fmt_meta_cap)(struct file *file, void *fh, int (*vidioc_g_fmt_meta_cap)(struct file *file, void *fh,
struct v4l2_format *f); struct v4l2_format *f);
int (*vidioc_g_fmt_meta_out)(struct file *file, void *fh,
struct v4l2_format *f);
/* VIDIOC_S_FMT handlers */ /* VIDIOC_S_FMT handlers */
int (*vidioc_s_fmt_vid_cap)(struct file *file, void *fh, int (*vidioc_s_fmt_vid_cap)(struct file *file, void *fh,
...@@ -370,6 +383,8 @@ struct v4l2_ioctl_ops { ...@@ -370,6 +383,8 @@ struct v4l2_ioctl_ops {
struct v4l2_format *f); struct v4l2_format *f);
int (*vidioc_s_fmt_meta_cap)(struct file *file, void *fh, int (*vidioc_s_fmt_meta_cap)(struct file *file, void *fh,
struct v4l2_format *f); struct v4l2_format *f);
int (*vidioc_s_fmt_meta_out)(struct file *file, void *fh,
struct v4l2_format *f);
/* VIDIOC_TRY_FMT handlers */ /* VIDIOC_TRY_FMT handlers */
int (*vidioc_try_fmt_vid_cap)(struct file *file, void *fh, int (*vidioc_try_fmt_vid_cap)(struct file *file, void *fh,
...@@ -398,6 +413,8 @@ struct v4l2_ioctl_ops { ...@@ -398,6 +413,8 @@ struct v4l2_ioctl_ops {
struct v4l2_format *f); struct v4l2_format *f);
int (*vidioc_try_fmt_meta_cap)(struct file *file, void *fh, int (*vidioc_try_fmt_meta_cap)(struct file *file, void *fh,
struct v4l2_format *f); struct v4l2_format *f);
int (*vidioc_try_fmt_meta_out)(struct file *file, void *fh,
struct v4l2_format *f);
/* Buffer handlers */ /* Buffer handlers */
int (*vidioc_reqbufs)(struct file *file, void *fh, int (*vidioc_reqbufs)(struct file *file, void *fh,
......
...@@ -145,6 +145,7 @@ enum v4l2_buf_type { ...@@ -145,6 +145,7 @@ enum v4l2_buf_type {
V4L2_BUF_TYPE_SDR_CAPTURE = 11, V4L2_BUF_TYPE_SDR_CAPTURE = 11,
V4L2_BUF_TYPE_SDR_OUTPUT = 12, V4L2_BUF_TYPE_SDR_OUTPUT = 12,
V4L2_BUF_TYPE_META_CAPTURE = 13, V4L2_BUF_TYPE_META_CAPTURE = 13,
V4L2_BUF_TYPE_META_OUTPUT = 14,
/* Deprecated, do not use */ /* Deprecated, do not use */
V4L2_BUF_TYPE_PRIVATE = 0x80, V4L2_BUF_TYPE_PRIVATE = 0x80,
}; };
...@@ -469,6 +470,7 @@ struct v4l2_capability { ...@@ -469,6 +470,7 @@ struct v4l2_capability {
#define V4L2_CAP_READWRITE 0x01000000 /* read/write systemcalls */ #define V4L2_CAP_READWRITE 0x01000000 /* read/write systemcalls */
#define V4L2_CAP_ASYNCIO 0x02000000 /* async I/O */ #define V4L2_CAP_ASYNCIO 0x02000000 /* async I/O */
#define V4L2_CAP_STREAMING 0x04000000 /* streaming I/O ioctls */ #define V4L2_CAP_STREAMING 0x04000000 /* streaming I/O ioctls */
#define V4L2_CAP_META_OUTPUT 0x08000000 /* Is a metadata output device */
#define V4L2_CAP_TOUCH 0x10000000 /* Is a touch device */ #define V4L2_CAP_TOUCH 0x10000000 /* Is a touch device */
......
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