[libcamera-devel] [PATCH v5 06/23] libcamera: PixelFormatInfo: Add functions stride and frameSize
Paul Elder
paul.elder at ideasonboard.com
Thu Jul 9 15:28:18 CEST 2020
Add member functions to PixelFormatInfo for calculating stride and frame
size. This will simplify existing code that calculates these things.
Signed-off-by: Paul Elder <paul.elder at ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
---
Changes in v5:
- changed default align parameter for stride() to 1
- added align parameter to frameSize()
Changes in v4:
- add overloaded frameSize() that takes array of strides
- add optional parameter to stride() for byte alignment
Changes in v3:
- rename functions to stride and frameSize, from bytesPerLine and
imageSize, respectively
Changes in v2:
- make these functions const
- add documentation
- inline DIV_ROUND_UP
---
include/libcamera/internal/formats.h | 6 +++
src/libcamera/formats.cpp | 80 ++++++++++++++++++++++++++++
2 files changed, 86 insertions(+)
diff --git a/include/libcamera/internal/formats.h b/include/libcamera/internal/formats.h
index 211da4a..cad41ad 100644
--- a/include/libcamera/internal/formats.h
+++ b/include/libcamera/internal/formats.h
@@ -53,6 +53,12 @@ public:
static const PixelFormatInfo &info(const PixelFormat &format);
static const PixelFormatInfo &info(const V4L2PixelFormat &format);
+ unsigned int stride(unsigned int width, unsigned int plane,
+ unsigned int align = 1) const;
+ unsigned int frameSize(const Size &size, unsigned int align = 1) const;
+ unsigned int frameSize(const Size &size,
+ const std::array<unsigned int, 3> &strides) const;
+
/* \todo Add support for non-contiguous memory planes */
const char *name;
PixelFormat format;
diff --git a/src/libcamera/formats.cpp b/src/libcamera/formats.cpp
index 6d96055..0f71061 100644
--- a/src/libcamera/formats.cpp
+++ b/src/libcamera/formats.cpp
@@ -732,4 +732,84 @@ const PixelFormatInfo &PixelFormatInfo::info(const V4L2PixelFormat &format)
return info->second;
}
+/**
+ * \brief Compute the stride
+ * \param[in] width The width of the line, in pixels
+ * \param[in] plane The index of the plane whose stride is to be computed
+ * \param[in] align The number of bytes to align to (1 for default alignment)
+ * \return The number of bytes necessary to store a line, or 0 if the
+ * PixelFormatInfo instance or the \a plane is not valid
+ */
+unsigned int PixelFormatInfo::stride(unsigned int width, unsigned int plane,
+ unsigned int align) const
+{
+ if (!isValid()) {
+ LOG(Formats, Warning) << "Invalid pixel format, stride is zero";
+ return 0;
+ }
+
+ if (plane > planes.size() || !planes[plane].bytesPerGroup) {
+ LOG(Formats, Warning) << "Invalid plane index, stride is zero";
+ return 0;
+ }
+
+ /* ceil(width / pixelsPerGroup) * bytesPerGroup */
+ unsigned int stride = (width + pixelsPerGroup - 1) / pixelsPerGroup
+ * planes[plane].bytesPerGroup;
+
+ /* ceil(stride / align) * align */
+ return (stride + align - 1) / align * align;
+}
+
+/**
+ * \brief Compute the number of bytes necessary to store a frame
+ * \param[in] size The size of the frame, in pixels
+ * \param[in] align The number of bytes to align to (1 for default alignment)
+ * \return The number of bytes necessary to store the frame, or 0 if the
+ * PixelFormatInfo instance is not valid
+ */
+unsigned int PixelFormatInfo::frameSize(const Size &size, unsigned int align) const
+{
+ /* stride * ceil(height / verticalSubSampling) */
+ unsigned int sum = 0;
+ for (unsigned int i = 0; i < 3; i++) {
+ unsigned int vertSubSample = planes[i].verticalSubSampling;
+ if (!vertSubSample)
+ continue;
+ sum += stride(size.width, i, align)
+ * ((size.height + vertSubSample - 1) / vertSubSample);
+ }
+
+ return sum;
+}
+
+/**
+ * \brief Compute the number of bytes necessary to store a frame
+ * \param[in] size The size of the frame, in pixels
+ * \param[in] strides The strides to use for each plane
+ *
+ * This function is an overloaded version that takes custom strides for each
+ * plane, to be used when the device has custom alignment constraints that
+ * can't be described by just an alignment value.
+ *
+ * \return The number of bytes necessary to store the frame, or 0 if the
+ * PixelFormatInfo instance is not valid
+ */
+unsigned int
+PixelFormatInfo::frameSize(const Size &size,
+ const std::array<unsigned int, 3> &strides) const
+{
+ /* stride * ceil(height / verticalSubSampling) */
+ unsigned int sum = 0;
+ for (unsigned int i = 0; i < 3; i++) {
+ unsigned int vertSubSample = planes[i].verticalSubSampling;
+ if (!vertSubSample)
+ continue;
+ sum += strides[i]
+ * ((size.height + vertSubSample - 1) / vertSubSample);
+ }
+
+ return sum;
+}
+
} /* namespace libcamera */
--
2.27.0
More information about the libcamera-devel
mailing list