[libcamera-devel] [PATCH v2 2/6] libcamera: v4l2_pixelformat: Move DRM/V4L2 format conversion
Kieran Bingham
kieran.bingham at ideasonboard.com
Thu Apr 30 11:45:10 CEST 2020
On 30/04/2020 04:07, Laurent Pinchart wrote:
> Move the DRM/V4L2 format conversion code from V4L2VideoDevice to
> V4L2PixelFormat. This is a more natural home for the code.
Reviewed-by: Kieran Bingham <kieran.bingham at ideasonboard.com>
Still applies to this version.
> Signed-off-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
> ---
> src/libcamera/include/v4l2_pixelformat.h | 4 +
> src/libcamera/include/v4l2_videodevice.h | 3 -
> src/libcamera/pipeline/uvcvideo/uvcvideo.cpp | 2 +-
> src/libcamera/v4l2_pixelformat.cpp | 134 +++++++++++++++++
> src/libcamera/v4l2_videodevice.cpp | 147 +------------------
> test/libtest/buffer_source.cpp | 4 +-
> 6 files changed, 143 insertions(+), 151 deletions(-)
>
> diff --git a/src/libcamera/include/v4l2_pixelformat.h b/src/libcamera/include/v4l2_pixelformat.h
> index 4d277569cb8c..0fe8a017de34 100644
> --- a/src/libcamera/include/v4l2_pixelformat.h
> +++ b/src/libcamera/include/v4l2_pixelformat.h
> @@ -36,6 +36,10 @@ public:
>
> std::string toString() const;
>
> + PixelFormat toPixelFormat() const;
> + static V4L2PixelFormat fromPixelFormat(const PixelFormat &pixelFormat,
> + bool multiplanar);
> +
> private:
> uint32_t fourcc_;
> };
> diff --git a/src/libcamera/include/v4l2_videodevice.h b/src/libcamera/include/v4l2_videodevice.h
> index ff64bb357c7e..982fee6bf740 100644
> --- a/src/libcamera/include/v4l2_videodevice.h
> +++ b/src/libcamera/include/v4l2_videodevice.h
> @@ -210,10 +210,7 @@ public:
> static V4L2VideoDevice *fromEntityName(const MediaDevice *media,
> const std::string &entity);
>
> - static PixelFormat toPixelFormat(V4L2PixelFormat v4l2Fourcc);
> V4L2PixelFormat toV4L2PixelFormat(const PixelFormat &pixelFormat);
> - static V4L2PixelFormat toV4L2PixelFormat(const PixelFormat &pixelFormat,
> - bool multiplanar);
>
> protected:
> std::string logPrefix() const;
> diff --git a/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp b/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp
> index 030ac6864752..455693264c2e 100644
> --- a/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp
> +++ b/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp
> @@ -166,7 +166,7 @@ CameraConfiguration *PipelineHandlerUVC::generateConfiguration(Camera *camera,
> std::inserter(deviceFormats, deviceFormats.begin()),
> [&](const decltype(v4l2Formats)::value_type &format) {
> return decltype(deviceFormats)::value_type{
> - data->video_->toPixelFormat(format.first),
> + format.first.toPixelFormat(),
> format.second
> };
> });
> diff --git a/src/libcamera/v4l2_pixelformat.cpp b/src/libcamera/v4l2_pixelformat.cpp
> index 57d65c380b0d..876f5de321f6 100644
> --- a/src/libcamera/v4l2_pixelformat.cpp
> +++ b/src/libcamera/v4l2_pixelformat.cpp
> @@ -103,4 +103,138 @@ std::string V4L2PixelFormat::toString() const
> return ss;
> }
>
> +/**
> + * \brief Convert the V4L2 pixel format to the corresponding PixelFormat
> + * \return The PixelFormat corresponding to the V4L2 pixel format
> + */
> +PixelFormat V4L2PixelFormat::toPixelFormat() const
> +{
> + switch (fourcc_) {
> + /* RGB formats. */
> + case V4L2_PIX_FMT_RGB24:
> + return PixelFormat(DRM_FORMAT_BGR888);
> + case V4L2_PIX_FMT_BGR24:
> + return PixelFormat(DRM_FORMAT_RGB888);
> + case V4L2_PIX_FMT_RGBA32:
> + return PixelFormat(DRM_FORMAT_ABGR8888);
> + case V4L2_PIX_FMT_ABGR32:
> + return PixelFormat(DRM_FORMAT_ARGB8888);
> + case V4L2_PIX_FMT_ARGB32:
> + return PixelFormat(DRM_FORMAT_BGRA8888);
> + case V4L2_PIX_FMT_BGRA32:
> + return PixelFormat(DRM_FORMAT_RGBA8888);
> +
> + /* YUV packed formats. */
> + case V4L2_PIX_FMT_YUYV:
> + return PixelFormat(DRM_FORMAT_YUYV);
> + case V4L2_PIX_FMT_YVYU:
> + return PixelFormat(DRM_FORMAT_YVYU);
> + case V4L2_PIX_FMT_UYVY:
> + return PixelFormat(DRM_FORMAT_UYVY);
> + case V4L2_PIX_FMT_VYUY:
> + return PixelFormat(DRM_FORMAT_VYUY);
> +
> + /* YUY planar formats. */
> + case V4L2_PIX_FMT_NV16:
> + case V4L2_PIX_FMT_NV16M:
> + return PixelFormat(DRM_FORMAT_NV16);
> + case V4L2_PIX_FMT_NV61:
> + case V4L2_PIX_FMT_NV61M:
> + return PixelFormat(DRM_FORMAT_NV61);
> + case V4L2_PIX_FMT_NV12:
> + case V4L2_PIX_FMT_NV12M:
> + return PixelFormat(DRM_FORMAT_NV12);
> + case V4L2_PIX_FMT_NV21:
> + case V4L2_PIX_FMT_NV21M:
> + return PixelFormat(DRM_FORMAT_NV21);
> +
> + /* Greyscale formats. */
> + case V4L2_PIX_FMT_GREY:
> + return PixelFormat(DRM_FORMAT_R8);
> +
> + /* Compressed formats. */
> + case V4L2_PIX_FMT_MJPEG:
> + return PixelFormat(DRM_FORMAT_MJPEG);
> +
> + /* V4L2 formats not yet supported by DRM. */
> + default:
> + LOG(V4L2, Warning)
> + << "Unsupported V4L2 pixel format "
> + << toString();
> + return PixelFormat();
> + }
> +}
> +
> +/**
> + * \brief Convert \a pixelFormat to its corresponding V4L2PixelFormat
> + * \param[in] pixelFormat The PixelFormat to convert
> + * \param[in] multiplanar V4L2 Multiplanar API support flag
> + *
> + * Multiple V4L2 formats may exist for one PixelFormat when the format uses
> + * multiple planes, as V4L2 defines separate 4CCs for contiguous and separate
> + * planes formats. Set the \a multiplanar parameter to false to select a format
> + * with contiguous planes, or to true to select a format with non-contiguous
> + * planes.
> + *
> + * \return The V4L2PixelFormat corresponding to \a pixelFormat
> + */
> +V4L2PixelFormat V4L2PixelFormat::fromPixelFormat(const PixelFormat &pixelFormat,
> + bool multiplanar)
> +{
> + switch (pixelFormat) {
> + /* RGB formats. */
> + case DRM_FORMAT_BGR888:
> + return V4L2PixelFormat(V4L2_PIX_FMT_RGB24);
> + case DRM_FORMAT_RGB888:
> + return V4L2PixelFormat(V4L2_PIX_FMT_BGR24);
> + case DRM_FORMAT_ABGR8888:
> + return V4L2PixelFormat(V4L2_PIX_FMT_RGBA32);
> + case DRM_FORMAT_ARGB8888:
> + return V4L2PixelFormat(V4L2_PIX_FMT_ABGR32);
> + case DRM_FORMAT_BGRA8888:
> + return V4L2PixelFormat(V4L2_PIX_FMT_ARGB32);
> + case DRM_FORMAT_RGBA8888:
> + return V4L2PixelFormat(V4L2_PIX_FMT_BGRA32);
> +
> + /* YUV packed formats. */
> + case DRM_FORMAT_YUYV:
> + return V4L2PixelFormat(V4L2_PIX_FMT_YUYV);
> + case DRM_FORMAT_YVYU:
> + return V4L2PixelFormat(V4L2_PIX_FMT_YVYU);
> + case DRM_FORMAT_UYVY:
> + return V4L2PixelFormat(V4L2_PIX_FMT_UYVY);
> + case DRM_FORMAT_VYUY:
> + return V4L2PixelFormat(V4L2_PIX_FMT_VYUY);
> +
> + /*
> + * YUY planar formats.
> + * \todo Add support for non-contiguous memory planes
> + * \todo Select the format variant not only based on \a multiplanar but
> + * also take into account the formats supported by the device.
> + */
> + case DRM_FORMAT_NV16:
> + return V4L2PixelFormat(V4L2_PIX_FMT_NV16);
> + case DRM_FORMAT_NV61:
> + return V4L2PixelFormat(V4L2_PIX_FMT_NV61);
> + case DRM_FORMAT_NV12:
> + return V4L2PixelFormat(V4L2_PIX_FMT_NV12);
> + case DRM_FORMAT_NV21:
> + return V4L2PixelFormat(V4L2_PIX_FMT_NV21);
> +
> + /* Greyscale formats. */
> + case DRM_FORMAT_R8:
> + return V4L2PixelFormat(V4L2_PIX_FMT_GREY);
> +
> + /* Compressed formats. */
> + case DRM_FORMAT_MJPEG:
> + return V4L2PixelFormat(V4L2_PIX_FMT_MJPEG);
> +
> + default:
> + LOG(V4L2, Warning)
> + << "Unsupported pixel format "
> + << pixelFormat.toString();
> + return V4L2PixelFormat();
> + }
> +}
> +
> } /* namespace libcamera */
> diff --git a/src/libcamera/v4l2_videodevice.cpp b/src/libcamera/v4l2_videodevice.cpp
> index 21df4f524212..e95b0c01cc85 100644
> --- a/src/libcamera/v4l2_videodevice.cpp
> +++ b/src/libcamera/v4l2_videodevice.cpp
> @@ -18,7 +18,6 @@
> #include <unistd.h>
> #include <vector>
>
> -#include <linux/drm_fourcc.h>
> #include <linux/version.h>
>
> #include <libcamera/event_notifier.h>
> @@ -1634,74 +1633,6 @@ V4L2VideoDevice *V4L2VideoDevice::fromEntityName(const MediaDevice *media,
> return new V4L2VideoDevice(mediaEntity);
> }
>
> -/**
> - * \brief Convert a \a v4l2Fourcc to the corresponding PixelFormat
> - * \param[in] v4l2Fourcc The V4L2 pixel format (V4L2_PIX_FORMAT_*)
> - * \return The PixelFormat corresponding to \a v4l2Fourcc
> - */
> -PixelFormat V4L2VideoDevice::toPixelFormat(V4L2PixelFormat v4l2Fourcc)
> -{
> - switch (v4l2Fourcc) {
> - /* RGB formats. */
> - case V4L2_PIX_FMT_RGB24:
> - return PixelFormat(DRM_FORMAT_BGR888);
> - case V4L2_PIX_FMT_BGR24:
> - return PixelFormat(DRM_FORMAT_RGB888);
> - case V4L2_PIX_FMT_RGBA32:
> - return PixelFormat(DRM_FORMAT_ABGR8888);
> - case V4L2_PIX_FMT_ABGR32:
> - return PixelFormat(DRM_FORMAT_ARGB8888);
> - case V4L2_PIX_FMT_ARGB32:
> - return PixelFormat(DRM_FORMAT_BGRA8888);
> - case V4L2_PIX_FMT_BGRA32:
> - return PixelFormat(DRM_FORMAT_RGBA8888);
> -
> - /* YUV packed formats. */
> - case V4L2_PIX_FMT_YUYV:
> - return PixelFormat(DRM_FORMAT_YUYV);
> - case V4L2_PIX_FMT_YVYU:
> - return PixelFormat(DRM_FORMAT_YVYU);
> - case V4L2_PIX_FMT_UYVY:
> - return PixelFormat(DRM_FORMAT_UYVY);
> - case V4L2_PIX_FMT_VYUY:
> - return PixelFormat(DRM_FORMAT_VYUY);
> -
> - /* YUY planar formats. */
> - case V4L2_PIX_FMT_NV16:
> - case V4L2_PIX_FMT_NV16M:
> - return PixelFormat(DRM_FORMAT_NV16);
> - case V4L2_PIX_FMT_NV61:
> - case V4L2_PIX_FMT_NV61M:
> - return PixelFormat(DRM_FORMAT_NV61);
> - case V4L2_PIX_FMT_NV12:
> - case V4L2_PIX_FMT_NV12M:
> - return PixelFormat(DRM_FORMAT_NV12);
> - case V4L2_PIX_FMT_NV21:
> - case V4L2_PIX_FMT_NV21M:
> - return PixelFormat(DRM_FORMAT_NV21);
> -
> - /* Greyscale formats. */
> - case V4L2_PIX_FMT_GREY:
> - return PixelFormat(DRM_FORMAT_R8);
> -
> - /* Compressed formats. */
> - case V4L2_PIX_FMT_MJPEG:
> - return PixelFormat(DRM_FORMAT_MJPEG);
> -
> - /* V4L2 formats not yet supported by DRM. */
> - default:
> - /*
> - * \todo We can't use LOG() in a static method of a Loggable
> - * class. Until we fix the logger, work around it.
> - */
> - libcamera::_log(__FILE__, __LINE__, _LOG_CATEGORY(V4L2)(),
> - LogWarning).stream()
> - << "Unsupported V4L2 pixel format "
> - << v4l2Fourcc.toString();
> - return PixelFormat();
> - }
> -}
> -
> /**
> * \brief Convert \a PixelFormat to its corresponding V4L2 FourCC
> * \param[in] pixelFormat The PixelFormat to convert
> @@ -1715,82 +1646,8 @@ PixelFormat V4L2VideoDevice::toPixelFormat(V4L2PixelFormat v4l2Fourcc)
> */
> V4L2PixelFormat V4L2VideoDevice::toV4L2PixelFormat(const PixelFormat &pixelFormat)
> {
> - return toV4L2PixelFormat(pixelFormat, caps_.isMultiplanar());
> -}
> -
> -/**
> - * \brief Convert \a pixelFormat to its corresponding V4L2 FourCC
> - * \param[in] pixelFormat The PixelFormat to convert
> - * \param[in] multiplanar V4L2 Multiplanar API support flag
> - *
> - * Multiple V4L2 formats may exist for one PixelFormat when the format uses
> - * multiple planes, as V4L2 defines separate 4CCs for contiguous and separate
> - * planes formats. Set the \a multiplanar parameter to false to select a format
> - * with contiguous planes, or to true to select a format with non-contiguous
> - * planes.
> - *
> - * \return The V4L2_PIX_FMT_* pixel format code corresponding to \a pixelFormat
> - */
> -V4L2PixelFormat V4L2VideoDevice::toV4L2PixelFormat(const PixelFormat &pixelFormat,
> - bool multiplanar)
> -{
> - switch (pixelFormat) {
> - /* RGB formats. */
> - case DRM_FORMAT_BGR888:
> - return V4L2PixelFormat(V4L2_PIX_FMT_RGB24);
> - case DRM_FORMAT_RGB888:
> - return V4L2PixelFormat(V4L2_PIX_FMT_BGR24);
> - case DRM_FORMAT_ABGR8888:
> - return V4L2PixelFormat(V4L2_PIX_FMT_RGBA32);
> - case DRM_FORMAT_ARGB8888:
> - return V4L2PixelFormat(V4L2_PIX_FMT_ABGR32);
> - case DRM_FORMAT_BGRA8888:
> - return V4L2PixelFormat(V4L2_PIX_FMT_ARGB32);
> - case DRM_FORMAT_RGBA8888:
> - return V4L2PixelFormat(V4L2_PIX_FMT_BGRA32);
> -
> - /* YUV packed formats. */
> - case DRM_FORMAT_YUYV:
> - return V4L2PixelFormat(V4L2_PIX_FMT_YUYV);
> - case DRM_FORMAT_YVYU:
> - return V4L2PixelFormat(V4L2_PIX_FMT_YVYU);
> - case DRM_FORMAT_UYVY:
> - return V4L2PixelFormat(V4L2_PIX_FMT_UYVY);
> - case DRM_FORMAT_VYUY:
> - return V4L2PixelFormat(V4L2_PIX_FMT_VYUY);
> -
> - /*
> - * YUY planar formats.
> - * \todo Add support for non-contiguous memory planes
> - * \todo Select the format variant not only based on \a multiplanar but
> - * also take into account the formats supported by the device.
> - */
> - case DRM_FORMAT_NV16:
> - return V4L2PixelFormat(V4L2_PIX_FMT_NV16);
> - case DRM_FORMAT_NV61:
> - return V4L2PixelFormat(V4L2_PIX_FMT_NV61);
> - case DRM_FORMAT_NV12:
> - return V4L2PixelFormat(V4L2_PIX_FMT_NV12);
> - case DRM_FORMAT_NV21:
> - return V4L2PixelFormat(V4L2_PIX_FMT_NV21);
> -
> - /* Greyscale formats. */
> - case DRM_FORMAT_R8:
> - return V4L2PixelFormat(V4L2_PIX_FMT_GREY);
> -
> - /* Compressed formats. */
> - case DRM_FORMAT_MJPEG:
> - return V4L2PixelFormat(V4L2_PIX_FMT_MJPEG);
> - }
> -
> - /*
> - * \todo We can't use LOG() in a static method of a Loggable
> - * class. Until we fix the logger, work around it.
> - */
> - libcamera::_log(__FILE__, __LINE__, _LOG_CATEGORY(V4L2)(),
> - LogWarning).stream()
> - << "Unsupported V4L2 pixel format " << pixelFormat.toString();
> - return {};
> + return V4L2PixelFormat::fromPixelFormat(pixelFormat,
> + caps_.isMultiplanar());
> }
>
> /**
> diff --git a/test/libtest/buffer_source.cpp b/test/libtest/buffer_source.cpp
> index dae3cb9f7a6c..d1dad2a0f8cf 100644
> --- a/test/libtest/buffer_source.cpp
> +++ b/test/libtest/buffer_source.cpp
> @@ -70,8 +70,8 @@ int BufferSource::allocate(const StreamConfiguration &config)
> }
>
> format.size = config.size;
> - format.fourcc = V4L2VideoDevice::toV4L2PixelFormat(config.pixelFormat,
> - false);
> + format.fourcc = V4L2PixelFormat::fromPixelFormat(config.pixelFormat,
> + false);
> if (video->setFormat(&format)) {
> std::cout << "Failed to set format on output device" << std::endl;
> return TestFail;
>
--
Regards
--
Kieran
More information about the libcamera-devel
mailing list