[libcamera-devel] [PATCH v5] libcamera:PixelFormat: Replace hex with format names
Laurent Pinchart
laurent.pinchart at ideasonboard.com
Sat Jun 20 01:10:56 CEST 2020
Hello,
On Fri, Jun 19, 2020 at 10:40:15PM +0100, Kieran Bingham wrote:
> On 19/06/2020 20:06, Kaaira Gupta wrote:
> > Print format names defined in formats namespace instead of the hex
> > values in toString() as they are easier to comprehend. For this add
> > a property of 'name' in PixelFormatInfo so as to map the formats
> > with their names. Print fourcc for formats which are not used in
> > libcamera.
>
> Excellent, this is really readable now - and ties in nicely with the new
> formats namespacing:
>
> >> Using camera VIMC Sensor B
> >> [66:02:15.314555780] [1159464] INFO VIMC vimc.cpp:189 Skipping unsupported pixel format RGB888
> >> [66:02:15.314729922] [1159464] INFO Camera camera.cpp:770 configuring streams: (0) 1920x1080-BGR888
> >> Capture until user interrupts by SIGINT
Much nicer indeed ! Thank you Kaaira for your perseverance :-)
> > Signed-off-by: Kaaira Gupta <kgupta at es.iitr.ac.in>
> > ---
> >
> > Changes since v4:
> > -Print libcamera defined names instead of fourcc.
> >
> > Changes since v3:
> > -shortened the texts.
> > -Removed default case as well.
> > -changed commit message and tests to reflect the changes.
> >
> > Changes since v2:
> > - Remove description for all vendors except for MIPI
> > - Change commit message to reflect this change.
> > - Change tests accordingly.
> >
> > Changes since v1:
> > - Replaced magic numbers with expressive values.
> > - Re-wrote ARM vendor's modifiers
> > - Re-wrote the vendors' map with a macro.
> > - Changed the copyrights in test file.
> > - Changed the tests.
> >
> > include/libcamera/internal/formats.h | 1 +
> > src/libcamera/formats.cpp | 40 +++++++++++++++++++++--
> > src/libcamera/pixel_format.cpp | 27 +++++++++++++--
> > test/meson.build | 1 +
> > test/pixel-format.cpp | 49 ++++++++++++++++++++++++++++
> > 5 files changed, 113 insertions(+), 5 deletions(-)
> > create mode 100644 test/pixel-format.cpp
> >
> > diff --git a/include/libcamera/internal/formats.h b/include/libcamera/internal/formats.h
> > index 4b172ef..8012721 100644
> > --- a/include/libcamera/internal/formats.h
> > +++ b/include/libcamera/internal/formats.h
> > @@ -46,6 +46,7 @@ public:
> > static const PixelFormatInfo &info(const PixelFormat &format);
> >
> > /* \todo Add support for non-contiguous memory planes */
> > + std::string name;
>
> I think this could be "const char * name" ?
s/\* /*/
> If that's the only thing to update, (and if it should be) then I can
> update this when applying if we get more RB tags, so no need to repost
> unless there are other comments.
>
> Reviewed-by: Kieran Bingham <kieran.bingham at ideasonboard.com>
>
> Although I do have a question below about std::hex vs utils::hex too..
>
> > PixelFormat format;
> > V4L2PixelFormat v4l2Format;
> > unsigned int bitsPerPixel;
> > diff --git a/src/libcamera/formats.cpp b/src/libcamera/formats.cpp
> > index 97e9867..2908409 100644
> > --- a/src/libcamera/formats.cpp
> > +++ b/src/libcamera/formats.cpp
> > @@ -169,6 +169,7 @@ namespace {
> > const std::map<PixelFormat, PixelFormatInfo> pixelFormatInfo{
> > /* RGB formats. */
> > { formats::BGR888, {
> > + .name = "BGR888",
> > .format = formats::BGR888,
> > .v4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_RGB24),
> > .bitsPerPixel = 24,
Unrelated to this patch, but I wonder if we should add more information
to formats.yaml and generate this map.
> > @@ -176,6 +177,7 @@ const std::map<PixelFormat, PixelFormatInfo> pixelFormatInfo{
> > .packed = false,
> > } },
> > { formats::RGB888, {
> > + .name = "RGB888",
> > .format = formats::RGB888,
> > .v4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_BGR24),
> > .bitsPerPixel = 24,
> > @@ -183,6 +185,7 @@ const std::map<PixelFormat, PixelFormatInfo> pixelFormatInfo{
> > .packed = false,
> > } },
> > { formats::ABGR8888, {
> > + .name = "ABGR8888",
> > .format = formats::ABGR8888,
> > .v4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_RGBA32),
> > .bitsPerPixel = 32,
> > @@ -190,6 +193,7 @@ const std::map<PixelFormat, PixelFormatInfo> pixelFormatInfo{
> > .packed = false,
> > } },
> > { formats::ARGB8888, {
> > + .name = "ARGB8888",
> > .format = formats::ARGB8888,
> > .v4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_ABGR32),
> > .bitsPerPixel = 32,
> > @@ -197,6 +201,7 @@ const std::map<PixelFormat, PixelFormatInfo> pixelFormatInfo{
> > .packed = false,
> > } },
> > { formats::BGRA8888, {
> > + .name = "BGRA8888",
> > .format = formats::BGRA8888,
> > .v4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_ARGB32),
> > .bitsPerPixel = 32,
> > @@ -204,6 +209,7 @@ const std::map<PixelFormat, PixelFormatInfo> pixelFormatInfo{
> > .packed = false,
> > } },
> > { formats::RGBA8888, {
> > + .name = "RGBA8888",
> > .format = formats::RGBA8888,
> > .v4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_BGRA32),
> > .bitsPerPixel = 32,
> > @@ -213,6 +219,7 @@ const std::map<PixelFormat, PixelFormatInfo> pixelFormatInfo{
> >
> > /* YUV packed formats. */
> > { formats::YUYV, {
> > + .name = "YUYV",
> > .format = formats::YUYV,
> > .v4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_YUYV),
> > .bitsPerPixel = 16,
> > @@ -220,6 +227,7 @@ const std::map<PixelFormat, PixelFormatInfo> pixelFormatInfo{
> > .packed = false,
> > } },
> > { formats::YVYU, {
> > + .name = "YVYU",
> > .format = formats::YVYU,
> > .v4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_YVYU),
> > .bitsPerPixel = 16,
> > @@ -227,6 +235,7 @@ const std::map<PixelFormat, PixelFormatInfo> pixelFormatInfo{
> > .packed = false,
> > } },
> > { formats::UYVY, {
> > + .name = "UYVY",
> > .format = formats::UYVY,
> > .v4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_UYVY),
> > .bitsPerPixel = 16,
> > @@ -234,6 +243,7 @@ const std::map<PixelFormat, PixelFormatInfo> pixelFormatInfo{
> > .packed = false,
> > } },
> > { formats::VYUY, {
> > + .name = "VYUY",
> > .format = formats::VYUY,
> > .v4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_VYUY),
> > .bitsPerPixel = 16,
> > @@ -243,6 +253,7 @@ const std::map<PixelFormat, PixelFormatInfo> pixelFormatInfo{
> >
> > /* YUV planar formats. */
> > { formats::NV16, {
> > + .name = "NV16",
> > .format = formats::NV16,
> > .v4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_NV16),
> > .bitsPerPixel = 16,
> > @@ -250,6 +261,7 @@ const std::map<PixelFormat, PixelFormatInfo> pixelFormatInfo{
> > .packed = false,
> > } },
> > { formats::NV61, {
> > + .name = "NV61",
> > .format = formats::NV61,
> > .v4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_NV61),
> > .bitsPerPixel = 16,
> > @@ -257,6 +269,7 @@ const std::map<PixelFormat, PixelFormatInfo> pixelFormatInfo{
> > .packed = false,
> > } },
> > { formats::NV12, {
> > + .name = "NV12",
> > .format = formats::NV12,
> > .v4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_NV12),
> > .bitsPerPixel = 12,
> > @@ -264,6 +277,7 @@ const std::map<PixelFormat, PixelFormatInfo> pixelFormatInfo{
> > .packed = false,
> > } },
> > { formats::NV21, {
> > + .name = "NV21",
> > .format = formats::NV21,
> > .v4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_NV21),
> > .bitsPerPixel = 12,
> > @@ -273,6 +287,7 @@ const std::map<PixelFormat, PixelFormatInfo> pixelFormatInfo{
> >
> > /* Greyscale formats. */
> > { formats::R8, {
> > + .name = "R8",
> > .format = formats::R8,
> > .v4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_GREY),
> > .bitsPerPixel = 8,
> > @@ -282,6 +297,7 @@ const std::map<PixelFormat, PixelFormatInfo> pixelFormatInfo{
> >
> > /* Bayer formats. */
> > { formats::SBGGR8, {
> > + .name = "SBGGR8",
> > .format = formats::SBGGR8,
> > .v4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_SBGGR8),
> > .bitsPerPixel = 8,
> > @@ -289,6 +305,7 @@ const std::map<PixelFormat, PixelFormatInfo> pixelFormatInfo{
> > .packed = false,
> > } },
> > { formats::SGBRG8, {
> > + .name = "SGBRG8",
> > .format = formats::SGBRG8,
> > .v4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_SGBRG8),
> > .bitsPerPixel = 8,
> > @@ -296,6 +313,7 @@ const std::map<PixelFormat, PixelFormatInfo> pixelFormatInfo{
> > .packed = false,
> > } },
> > { formats::SGRBG8, {
> > + .name = "SGRBG8",
> > .format = formats::SGRBG8,
> > .v4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_SGRBG8),
> > .bitsPerPixel = 8,
> > @@ -303,6 +321,7 @@ const std::map<PixelFormat, PixelFormatInfo> pixelFormatInfo{
> > .packed = false,
> > } },
> > { formats::SRGGB8, {
> > + .name = "SRGGB8",
> > .format = formats::SRGGB8,
> > .v4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_SRGGB8),
> > .bitsPerPixel = 8,
> > @@ -310,6 +329,7 @@ const std::map<PixelFormat, PixelFormatInfo> pixelFormatInfo{
> > .packed = false,
> > } },
> > { formats::SBGGR10, {
> > + .name = "SBGGR10",
> > .format = formats::SBGGR10,
> > .v4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_SBGGR10),
> > .bitsPerPixel = 10,
> > @@ -317,6 +337,7 @@ const std::map<PixelFormat, PixelFormatInfo> pixelFormatInfo{
> > .packed = false,
> > } },
> > { formats::SGBRG10, {
> > + .name = "SGBRG10",
> > .format = formats::SGBRG10,
> > .v4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_SGBRG10),
> > .bitsPerPixel = 10,
> > @@ -324,6 +345,7 @@ const std::map<PixelFormat, PixelFormatInfo> pixelFormatInfo{
> > .packed = false,
> > } },
> > { formats::SGRBG10, {
> > + .name = "SGRBG10",
> > .format = formats::SGRBG10,
> > .v4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_SGRBG10),
> > .bitsPerPixel = 10,
> > @@ -331,6 +353,7 @@ const std::map<PixelFormat, PixelFormatInfo> pixelFormatInfo{
> > .packed = false,
> > } },
> > { formats::SRGGB10, {
> > + .name = "SRGGB10",
> > .format = formats::SRGGB10,
> > .v4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_SRGGB10),
> > .bitsPerPixel = 10,
> > @@ -338,6 +361,7 @@ const std::map<PixelFormat, PixelFormatInfo> pixelFormatInfo{
> > .packed = false,
> > } },
> > { formats::SBGGR10_CSI2P, {
> > + .name = "SBGGR10_CSI2P",
> > .format = formats::SBGGR10_CSI2P,
> > .v4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_SBGGR10P),
> > .bitsPerPixel = 10,
> > @@ -345,6 +369,7 @@ const std::map<PixelFormat, PixelFormatInfo> pixelFormatInfo{
> > .packed = true,
> > } },
> > { formats::SGBRG10_CSI2P, {
> > + .name = "SGBRG10_CSI2P",
> > .format = formats::SGBRG10_CSI2P,
> > .v4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_SGBRG10P),
> > .bitsPerPixel = 10,
> > @@ -352,6 +377,7 @@ const std::map<PixelFormat, PixelFormatInfo> pixelFormatInfo{
> > .packed = true,
> > } },
> > { formats::SGRBG10_CSI2P, {
> > + .name = "SGRBG10_CSI2P",
> > .format = formats::SGRBG10_CSI2P,
> > .v4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_SGRBG10P),
> > .bitsPerPixel = 10,
> > @@ -359,6 +385,7 @@ const std::map<PixelFormat, PixelFormatInfo> pixelFormatInfo{
> > .packed = true,
> > } },
> > { formats::SRGGB10_CSI2P, {
> > + .name = "SRGGB10_CSI2P",
> > .format = formats::SRGGB10_CSI2P,
> > .v4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_SRGGB10P),
> > .bitsPerPixel = 10,
> > @@ -366,6 +393,7 @@ const std::map<PixelFormat, PixelFormatInfo> pixelFormatInfo{
> > .packed = true,
> > } },
> > { formats::SBGGR12, {
> > + .name = "SBGGR12",
> > .format = formats::SBGGR12,
> > .v4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_SBGGR12),
> > .bitsPerPixel = 12,
> > @@ -373,6 +401,7 @@ const std::map<PixelFormat, PixelFormatInfo> pixelFormatInfo{
> > .packed = false,
> > } },
> > { formats::SGBRG12, {
> > + .name = "SGBRG12",
> > .format = formats::SGBRG12,
> > .v4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_SGBRG12),
> > .bitsPerPixel = 12,
> > @@ -380,6 +409,7 @@ const std::map<PixelFormat, PixelFormatInfo> pixelFormatInfo{
> > .packed = false,
> > } },
> > { formats::SGRBG12, {
> > + .name = "SGRBG12",
> > .format = formats::SGRBG12,
> > .v4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_SGRBG12),
> > .bitsPerPixel = 12,
> > @@ -387,6 +417,7 @@ const std::map<PixelFormat, PixelFormatInfo> pixelFormatInfo{
> > .packed = false,
> > } },
> > { formats::SRGGB12, {
> > + .name = "SRGGB12",
> > .format = formats::SRGGB12,
> > .v4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_SRGGB12),
> > .bitsPerPixel = 12,
> > @@ -394,6 +425,7 @@ const std::map<PixelFormat, PixelFormatInfo> pixelFormatInfo{
> > .packed = false,
> > } },
> > { formats::SBGGR12_CSI2P, {
> > + .name = "SBGGR12_CSI2P",
> > .format = formats::SBGGR12_CSI2P,
> > .v4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_SBGGR12P),
> > .bitsPerPixel = 12,
> > @@ -401,6 +433,7 @@ const std::map<PixelFormat, PixelFormatInfo> pixelFormatInfo{
> > .packed = true,
> > } },
> > { formats::SGBRG12_CSI2P, {
> > + .name = "SGBRG12_CSI2P",
> > .format = formats::SGBRG12_CSI2P,
> > .v4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_SGBRG12P),
> > .bitsPerPixel = 12,
> > @@ -408,6 +441,7 @@ const std::map<PixelFormat, PixelFormatInfo> pixelFormatInfo{
> > .packed = true,
> > } },
> > { formats::SGRBG12_CSI2P, {
> > + .name = "SGRBG12_CSI2P",
> > .format = formats::SGRBG12_CSI2P,
> > .v4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_SGRBG12P),
> > .bitsPerPixel = 12,
> > @@ -415,6 +449,7 @@ const std::map<PixelFormat, PixelFormatInfo> pixelFormatInfo{
> > .packed = true,
> > } },
> > { formats::SRGGB12_CSI2P, {
> > + .name = "SRGGB12_CSI2P",
> > .format = formats::SRGGB12_CSI2P,
> > .v4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_SRGGB12P),
> > .bitsPerPixel = 12,
> > @@ -424,6 +459,7 @@ const std::map<PixelFormat, PixelFormatInfo> pixelFormatInfo{
> >
> > /* Compressed formats. */
> > { formats::MJPEG, {
> > + .name = "MJPEG",
> > .format = formats::MJPEG,
> > .v4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_MJPEG),
> > .bitsPerPixel = 0,
> > @@ -453,8 +489,8 @@ const PixelFormatInfo &PixelFormatInfo::info(const PixelFormat &format)
> > const auto iter = pixelFormatInfo.find(format);
> > if (iter == pixelFormatInfo.end()) {
> > LOG(Formats, Warning)
> > - << "Unsupported pixel format "
> > - << format.toString();
> > + << "Unsupported pixel format 0x"
> > + << std::hex << format.fourcc();
>
> Does utils::hex(format.fourcc()) make any difference here?
utils::hex() will automatically pad the output string to the size of the
field (8 characters in this case). I think it would be nicer to use it
here. It also resets the formatting options of the stream to avoid
having to add a std::dec after the argument, but that won't make a
difference here as the FourCC is last.
> > return invalid;
> > }
> >
> > diff --git a/src/libcamera/pixel_format.cpp b/src/libcamera/pixel_format.cpp
> > index f191851..07e7af0 100644
> > --- a/src/libcamera/pixel_format.cpp
> > +++ b/src/libcamera/pixel_format.cpp
> > @@ -6,6 +6,7 @@
> > */
> >
> > #include <libcamera/formats.h>
> > +#include "libcamera/internal/formats.h"
> > #include <libcamera/pixel_format.h>
We put the internal headers after the external ones, with a blank line
between the two groups.
> >
> > /**
> > @@ -104,9 +105,29 @@ bool PixelFormat::operator<(const PixelFormat &other) const
> > */
> > std::string PixelFormat::toString() const
> > {
> > - char str[11];
> > - snprintf(str, 11, "0x%08x", fourcc_);
> > - return str;
> > + PixelFormat format = PixelFormat(fourcc_, modifier_);
> > + const PixelFormatInfo &info = PixelFormatInfo::info(format);
How about
const PixelFormatInfo &info = PixelFormatInfo::info(*this);
> > +
> > + if (!info.isValid()) {
> > + if (format == PixelFormat())
And here,
if (!isValid())
With that, you can drop the local format variable.
> > + return "<INVALID>";
> > +
> > + char fourcc[7] = { '<',
> > + static_cast<char>(fourcc_ & 0x7f),
> > + static_cast<char>((fourcc_ >> 8) & 0x7f),
> > + static_cast<char>((fourcc_ >> 16) & 0x7f),
> > + static_cast<char>((fourcc_ >> 24) & 0x7f),
The isprint() should take care of non-printable characters, do we need
the & 0x7f ?
> > + '>' };
> > +
> > + for (unsigned int i = 1; i < 5; i++) {
> > + if (!isprint(fourcc[i]))
> > + fourcc[i] = '.';
> > + }
> > +
> > + return fourcc;
> > + }
> > +
> > + return info.name;
> > }
> >
> > } /* namespace libcamera */
> > diff --git a/test/meson.build b/test/meson.build
> > index a868813..7808a26 100644
> > --- a/test/meson.build
> > +++ b/test/meson.build
> > @@ -34,6 +34,7 @@ internal_tests = [
> > ['message', 'message.cpp'],
> > ['object', 'object.cpp'],
> > ['object-invoke', 'object-invoke.cpp'],
> > + ['pixel-format', 'pixel-format.cpp'],
> > ['signal-threads', 'signal-threads.cpp'],
> > ['threads', 'threads.cpp'],
> > ['timer', 'timer.cpp'],
> > diff --git a/test/pixel-format.cpp b/test/pixel-format.cpp
> > new file mode 100644
> > index 0000000..5b9cdc9
> > --- /dev/null
> > +++ b/test/pixel-format.cpp
> > @@ -0,0 +1,49 @@
> > +/* SPDX-License-Identifier: GPL-2.0-or-later */
> > +/*
> > + * Copyright (C) 2020, Kaaira Gupta
> > + * libcamera pixel format handling test
> > + */
> > +
> > +#include <iostream>
> > +#include <vector>
> > +
> > +#include <libcamera/formats.h>
> > +#include <libcamera/pixel_format.h>
> > +
> > +#include "test.h"
> > +
> > +using namespace std;
> > +using namespace libcamera;
> > +
> > +class PixelFormatTest : public Test
> > +{
> > +protected:
> > + int run()
> > + {
> > + std::vector<std::pair<PixelFormat, const char *>> formatsMap{
> > + { formats::R8, "R8" },
> > + { formats::SRGGB10_CSI2P, "SRGGB10_CSI2P" },
> > + { PixelFormat(0, 0), "<INVALID>" },
> > + { PixelFormat(0x20203843), "<C8 >" }
> > + };
> > +
> > + for (const auto &format : formatsMap) {
> > + if ((format.first).toString() != format.second) {
> > + cerr << "Failed to convert PixelFormat "
> > + << format.first.fourcc() << " to string"
Maybe utils::hex(format.first.fourcc()) ?
Only minor changes, with these addressed,
Reviewed-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
> > + << endl;
> > + return TestFail;
> > + }
> > + }
> > +
> > + if (PixelFormat().toString() != "<INVALID>") {
> > + cerr << "Failed to convert default PixelFormat to string"
> > + << endl;
> > + return TestFail;
> > + }
> > +
> > + return TestPass;
> > + }
> > +};
> > +
> > +TEST_REGISTER(PixelFormatTest)
--
Regards,
Laurent Pinchart
More information about the libcamera-devel
mailing list