From: Ezequiel Garcia <ezequiel@collabora.com>
To: linux-media@vger.kernel.org
Cc: Hans Verkuil <hans.verkuil@cisco.com>,
kernel@collabora.com,
Nicolas Dufresne <nicolas.dufresne@collabora.com>,
Tomasz Figa <tfiga@chromium.org>,
linux-rockchip@lists.infradead.org,
Heiko Stuebner <heiko@sntech.de>, Jonas Karlman <jonas@kwiboo.se>,
Ezequiel Garcia <ezequiel@collabora.com>
Subject: [PATCH v2 02/11] media: Introduce helpers to fill pixel format structs
Date: Mon, 4 Mar 2019 16:25:20 -0300 [thread overview]
Message-ID: <20190304192529.14200-3-ezequiel@collabora.com> (raw)
In-Reply-To: <20190304192529.14200-1-ezequiel@collabora.com>
Add two new API helpers, v4l2_fill_pixfmt and v4l2_fill_pixfmt_mp,
to be used by drivers to calculate plane sizes and bytes per lines.
Note that driver-specific padding and alignment are not
taken into account, and must be done by drivers using this API.
Signed-off-by: Ezequiel Garcia <ezequiel@collabora.com>
---
drivers/media/v4l2-core/v4l2-common.c | 186 ++++++++++++++++++++++++++
include/media/v4l2-common.h | 32 +++++
2 files changed, 218 insertions(+)
diff --git a/drivers/media/v4l2-core/v4l2-common.c b/drivers/media/v4l2-core/v4l2-common.c
index 663730f088cd..11a16bb3efda 100644
--- a/drivers/media/v4l2-core/v4l2-common.c
+++ b/drivers/media/v4l2-core/v4l2-common.c
@@ -44,6 +44,7 @@
* Added Gerd Knorrs v4l1 enhancements (Justin Schoeman)
*/
+#include <linux/ctype.h>
#include <linux/module.h>
#include <linux/types.h>
#include <linux/kernel.h>
@@ -445,3 +446,188 @@ int v4l2_s_parm_cap(struct video_device *vdev,
return ret;
}
EXPORT_SYMBOL_GPL(v4l2_s_parm_cap);
+
+static char printable_char(int c)
+{
+ return isascii(c) && isprint(c) ? c : '?';
+}
+
+const char *v4l2_get_fourcc_name(uint32_t format)
+{
+ static char buf[8];
+
+ snprintf(buf, 8,
+ "%c%c%c%c%s",
+ printable_char(format & 0xff),
+ printable_char((format >> 8) & 0xff),
+ printable_char((format >> 16) & 0xff),
+ printable_char((format >> 24) & 0x7f),
+ (format & BIT(31)) ? "-BE" : "");
+
+ return buf;
+}
+EXPORT_SYMBOL(v4l2_get_fourcc_name);
+
+const struct v4l2_format_info *v4l2_format_info(u32 format)
+{
+ static const struct v4l2_format_info formats[] = {
+ /* RGB formats */
+ { .format = V4L2_PIX_FMT_BGR24, .mem_planes = 1, .comp_planes = 1, .bpp = { 3, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
+ { .format = V4L2_PIX_FMT_RGB24, .mem_planes = 1, .comp_planes = 1, .bpp = { 3, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
+ { .format = V4L2_PIX_FMT_HSV24, .mem_planes = 1, .comp_planes = 1, .bpp = { 3, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
+ { .format = V4L2_PIX_FMT_BGR32, .mem_planes = 1, .comp_planes = 1, .bpp = { 4, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
+ { .format = V4L2_PIX_FMT_XBGR32, .mem_planes = 1, .comp_planes = 1, .bpp = { 4, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
+ { .format = V4L2_PIX_FMT_RGB32, .mem_planes = 1, .comp_planes = 1, .bpp = { 4, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
+ { .format = V4L2_PIX_FMT_XRGB32, .mem_planes = 1, .comp_planes = 1, .bpp = { 4, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
+ { .format = V4L2_PIX_FMT_HSV32, .mem_planes = 1, .comp_planes = 1, .bpp = { 4, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
+ { .format = V4L2_PIX_FMT_ARGB32, .mem_planes = 1, .comp_planes = 1, .bpp = { 4, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
+ { .format = V4L2_PIX_FMT_ABGR32, .mem_planes = 1, .comp_planes = 1, .bpp = { 4, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
+ { .format = V4L2_PIX_FMT_GREY, .mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
+
+ /* YUV packed formats */
+ { .format = V4L2_PIX_FMT_YUYV, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .hdiv = 2, .vdiv = 1 },
+ { .format = V4L2_PIX_FMT_YVYU, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .hdiv = 2, .vdiv = 1 },
+ { .format = V4L2_PIX_FMT_UYVY, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .hdiv = 2, .vdiv = 1 },
+ { .format = V4L2_PIX_FMT_VYUY, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .hdiv = 2, .vdiv = 1 },
+
+ /* YUV planar formats */
+ { .format = V4L2_PIX_FMT_NV12, .mem_planes = 1, .comp_planes = 2, .bpp = { 1, 2, 0, 0 }, .hdiv = 2, .vdiv = 2 },
+ { .format = V4L2_PIX_FMT_NV21, .mem_planes = 1, .comp_planes = 2, .bpp = { 1, 2, 0, 0 }, .hdiv = 2, .vdiv = 2 },
+ { .format = V4L2_PIX_FMT_NV16, .mem_planes = 1, .comp_planes = 2, .bpp = { 1, 2, 0, 0 }, .hdiv = 2, .vdiv = 1 },
+ { .format = V4L2_PIX_FMT_NV61, .mem_planes = 1, .comp_planes = 2, .bpp = { 1, 2, 0, 0 }, .hdiv = 2, .vdiv = 1 },
+ { .format = V4L2_PIX_FMT_NV24, .mem_planes = 1, .comp_planes = 2, .bpp = { 1, 2, 0, 0 }, .hdiv = 1, .vdiv = 1 },
+ { .format = V4L2_PIX_FMT_NV42, .mem_planes = 1, .comp_planes = 2, .bpp = { 1, 2, 0, 0 }, .hdiv = 1, .vdiv = 1 },
+
+ { .format = V4L2_PIX_FMT_YUV410, .mem_planes = 1, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .hdiv = 4, .vdiv = 4 },
+ { .format = V4L2_PIX_FMT_YVU410, .mem_planes = 1, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .hdiv = 4, .vdiv = 4 },
+ { .format = V4L2_PIX_FMT_YUV411P, .mem_planes = 1, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .hdiv = 4, .vdiv = 1 },
+ { .format = V4L2_PIX_FMT_YUV420, .mem_planes = 1, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .hdiv = 2, .vdiv = 2 },
+ { .format = V4L2_PIX_FMT_YVU420, .mem_planes = 1, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .hdiv = 2, .vdiv = 2 },
+ { .format = V4L2_PIX_FMT_YUV422P, .mem_planes = 1, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .hdiv = 2, .vdiv = 1 },
+
+ /* YUV planar formats, non contiguous variant */
+ { .format = V4L2_PIX_FMT_YUV420M, .mem_planes = 3, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .hdiv = 2, .vdiv = 2 },
+ { .format = V4L2_PIX_FMT_YVU420M, .mem_planes = 3, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .hdiv = 2, .vdiv = 2 },
+ { .format = V4L2_PIX_FMT_YUV422M, .mem_planes = 3, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .hdiv = 2, .vdiv = 1 },
+ { .format = V4L2_PIX_FMT_YVU422M, .mem_planes = 3, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .hdiv = 2, .vdiv = 1 },
+ { .format = V4L2_PIX_FMT_YUV444M, .mem_planes = 3, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .hdiv = 1, .vdiv = 1 },
+ { .format = V4L2_PIX_FMT_YVU444M, .mem_planes = 3, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .hdiv = 1, .vdiv = 1 },
+
+ { .format = V4L2_PIX_FMT_NV12M, .mem_planes = 2, .comp_planes = 2, .bpp = { 1, 2, 0, 0 }, .hdiv = 2, .vdiv = 2 },
+ { .format = V4L2_PIX_FMT_NV21M, .mem_planes = 2, .comp_planes = 2, .bpp = { 1, 2, 0, 0 }, .hdiv = 2, .vdiv = 2 },
+ { .format = V4L2_PIX_FMT_NV16M, .mem_planes = 2, .comp_planes = 2, .bpp = { 1, 2, 0, 0 }, .hdiv = 2, .vdiv = 1 },
+ { .format = V4L2_PIX_FMT_NV61M, .mem_planes = 2, .comp_planes = 2, .bpp = { 1, 2, 0, 0 }, .hdiv = 2, .vdiv = 1 },
+ };
+ unsigned int i;
+
+ for (i = 0; i < ARRAY_SIZE(formats); ++i)
+ if (formats[i].format == format)
+ return &formats[i];
+ return NULL;
+}
+EXPORT_SYMBOL(v4l2_format_info);
+
+static inline unsigned int v4l2_format_block_width(const struct v4l2_format_info *info, int plane)
+{
+ if (!info->block_w[plane])
+ return 1;
+ return info->block_w[plane];
+}
+
+static inline unsigned int v4l2_format_block_height(const struct v4l2_format_info *info, int plane)
+{
+ if (!info->block_h[plane])
+ return 1;
+ return info->block_h[plane];
+}
+
+int v4l2_fill_pixfmt_mp(struct v4l2_pix_format_mplane *pixfmt,
+ int pixelformat, int width, int height)
+{
+ const struct v4l2_format_info *info;
+ struct v4l2_plane_pix_format *plane;
+ int i;
+
+ info = v4l2_format_info(pixelformat);
+ if (!info)
+ return -EINVAL;
+
+ pixfmt->width = width;
+ pixfmt->height = height;
+ pixfmt->pixelformat = pixelformat;
+ pixfmt->num_planes = info->mem_planes;
+
+ if (info->mem_planes == 1) {
+ plane = &pixfmt->plane_fmt[0];
+ plane->bytesperline = ALIGN(width, v4l2_format_block_width(info, 0)) * info->bpp[0];
+ plane->sizeimage = 0;
+
+ for (i = 0; i < info->comp_planes; i++) {
+ unsigned int hdiv = (i == 0) ? 1 : info->hdiv;
+ unsigned int vdiv = (i == 0) ? 1 : info->vdiv;
+ unsigned int aligned_width;
+ unsigned int aligned_height;
+
+ aligned_width = ALIGN(width, v4l2_format_block_width(info, i));
+ aligned_height = ALIGN(height, v4l2_format_block_height(info, i));
+
+ plane->sizeimage += info->bpp[i] *
+ DIV_ROUND_UP(aligned_width, hdiv) *
+ DIV_ROUND_UP(aligned_height, vdiv);
+ }
+ } else {
+ for (i = 0; i < info->comp_planes; i++) {
+ unsigned int hdiv = (i == 0) ? 1 : info->hdiv;
+ unsigned int vdiv = (i == 0) ? 1 : info->vdiv;
+ unsigned int aligned_width;
+ unsigned int aligned_height;
+
+ aligned_width = ALIGN(width, v4l2_format_block_width(info, i));
+ aligned_height = ALIGN(height, v4l2_format_block_height(info, i));
+
+ plane = &pixfmt->plane_fmt[i];
+ plane->bytesperline =
+ info->bpp[i] * DIV_ROUND_UP(aligned_width, hdiv);
+ plane->sizeimage =
+ plane->bytesperline * DIV_ROUND_UP(aligned_height, vdiv);
+ }
+ }
+ return 0;
+}
+EXPORT_SYMBOL_GPL(v4l2_fill_pixfmt_mp);
+
+int v4l2_fill_pixfmt(struct v4l2_pix_format *pixfmt, int pixelformat, int width, int height)
+{
+ const struct v4l2_format_info *info;
+ int i;
+
+ info = v4l2_format_info(pixelformat);
+ if (!info)
+ return -EINVAL;
+
+ /* Single planar API cannot be used for multi plane formats. */
+ if (info->mem_planes > 1)
+ return -EINVAL;
+
+ pixfmt->width = width;
+ pixfmt->height = height;
+ pixfmt->pixelformat = pixelformat;
+ pixfmt->bytesperline = ALIGN(width, v4l2_format_block_width(info, 0)) * info->bpp[0];
+ pixfmt->sizeimage = 0;
+
+ for (i = 0; i < info->comp_planes; i++) {
+ unsigned int hdiv = (i == 0) ? 1 : info->hdiv;
+ unsigned int vdiv = (i == 0) ? 1 : info->vdiv;
+ unsigned int aligned_width;
+ unsigned int aligned_height;
+
+ aligned_width = ALIGN(width, v4l2_format_block_width(info, i));
+ aligned_height = ALIGN(height, v4l2_format_block_height(info, i));
+
+ pixfmt->sizeimage += info->bpp[i] *
+ DIV_ROUND_UP(aligned_width, hdiv) *
+ DIV_ROUND_UP(aligned_height, vdiv);
+ }
+ return 0;
+}
+EXPORT_SYMBOL_GPL(v4l2_fill_pixfmt);
diff --git a/include/media/v4l2-common.h b/include/media/v4l2-common.h
index 2b93cb281fa5..937b74a946cd 100644
--- a/include/media/v4l2-common.h
+++ b/include/media/v4l2-common.h
@@ -392,4 +392,36 @@ int v4l2_s_parm_cap(struct video_device *vdev,
((u64)(a).numerator * (b).denominator OP \
(u64)(b).numerator * (a).denominator)
+/* ------------------------------------------------------------------------- */
+
+/* Pixel format and FourCC helpers */
+
+/**
+ * struct v4l2_format_info - information about a V4L2 format
+ * @format: 4CC format identifier (V4L2_PIX_FMT_*)
+ * @mem_planes: Number of memory planes, which includes the alpha plane (1 to 4).
+ * @comp_planes: Number of component planes, which includes the alpha plane (1 to 4).
+ * @bpp: Array of per-plane bytes per pixel
+ * @hdiv: Horizontal chroma subsampling factor
+ * @vdiv: Vertical chroma subsampling factor
+ */
+struct v4l2_format_info {
+ u32 format;
+ u8 mem_planes;
+ u8 comp_planes;
+ u8 bpp[4];
+ u8 hdiv;
+ u8 vdiv;
+ u8 block_w[4];
+ u8 block_h[4];
+};
+
+const struct v4l2_format_info *v4l2_format_info(u32 format);
+const char *v4l2_get_fourcc_name(u32 format);
+
+int v4l2_fill_pixfmt(struct v4l2_pix_format *pixfmt, int pixelformat,
+ int width, int height);
+int v4l2_fill_pixfmt_mp(struct v4l2_pix_format_mplane *pixfmt, int pixelformat,
+ int width, int height);
+
#endif /* V4L2_COMMON_H_ */
--
2.20.1
next prev parent reply other threads:[~2019-03-04 19:26 UTC|newest]
Thread overview: 32+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-03-04 19:25 [PATCH v2 00/11] Add MPEG-2 decoding to Rockchip VPU Ezequiel Garcia
2019-03-04 19:25 ` [PATCH v2 01/11] rockchip/vpu: Rename pixel format helpers Ezequiel Garcia
2019-03-04 19:25 ` Ezequiel Garcia [this message]
2019-03-12 8:29 ` [PATCH v2 02/11] media: Introduce helpers to fill pixel format structs Hans Verkuil
2019-03-22 17:29 ` Ezequiel Garcia
2019-03-25 14:32 ` Emil Velikov
2019-03-04 19:25 ` [PATCH v2 03/11] rockchip/vpu: Use pixel format helpers Ezequiel Garcia
2019-03-04 19:25 ` [PATCH v2 04/11] rockchip/vpu: Use v4l2_m2m_buf_copy_metadata Ezequiel Garcia
2019-03-04 19:25 ` [PATCH v2 05/11] rockchip/vpu: Cleanup macroblock alignment Ezequiel Garcia
2019-03-04 19:25 ` [PATCH v2 06/11] rockchip/vpu: Cleanup JPEG bounce buffer management Ezequiel Garcia
2019-03-28 6:15 ` Tomasz Figa
2019-03-28 18:30 ` Ezequiel Garcia
2019-03-29 3:21 ` Tomasz Figa
2019-03-04 19:25 ` [PATCH v2 07/11] rockchip/vpu: Open-code media controller register Ezequiel Garcia
2019-03-28 7:11 ` Tomasz Figa
2019-03-28 20:05 ` Ezequiel Garcia
2019-03-29 7:43 ` Tomasz Figa
2019-03-04 19:25 ` [PATCH v2 08/11] rockchip/vpu: Support the Request API Ezequiel Garcia
2019-03-28 7:20 ` Tomasz Figa
2019-03-28 13:59 ` Hans Verkuil
2019-03-29 3:23 ` Tomasz Figa
2019-03-28 19:07 ` Ezequiel Garcia
2019-03-04 19:25 ` [PATCH v2 09/11] rockchip/vpu: Add decoder boilerplate Ezequiel Garcia
2019-03-28 9:57 ` Tomasz Figa
2019-03-28 19:23 ` Ezequiel Garcia
2019-03-29 7:40 ` Tomasz Figa
2019-03-04 19:25 ` [PATCH v2 10/11] rockchip/vpu: Add support for non-standard controls Ezequiel Garcia
2019-04-01 3:14 ` Tomasz Figa
2019-04-12 19:25 ` Ezequiel Garcia
2019-04-15 4:07 ` Tomasz Figa
2019-03-04 19:25 ` [PATCH v2 11/11] rockchip/vpu: Add support for MPEG-2 decoding Ezequiel Garcia
2019-04-01 3:52 ` Tomasz Figa
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20190304192529.14200-3-ezequiel@collabora.com \
--to=ezequiel@collabora.com \
--cc=hans.verkuil@cisco.com \
--cc=heiko@sntech.de \
--cc=jonas@kwiboo.se \
--cc=kernel@collabora.com \
--cc=linux-media@vger.kernel.org \
--cc=linux-rockchip@lists.infradead.org \
--cc=nicolas.dufresne@collabora.com \
--cc=tfiga@chromium.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).