From 2bc657f47b9fd5690697b1adc805e0f923f3ef8a Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Thu, 30 Apr 2020 03:16:53 +0300 Subject: libcamera: v4l2_pixelformat: Move DRM/V4L2 format conversion Move the DRM/V4L2 format conversion code from V4L2VideoDevice to V4L2PixelFormat. This is a more natural home for the code. Signed-off-by: Laurent Pinchart Reviewed-by: Kieran Bingham --- 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 4d277569..0fe8a017 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 ff64bb35..982fee6b 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 030ac686..45569326 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 57d65c38..876f5de3 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 21df4f52..e95b0c01 100644 --- a/src/libcamera/v4l2_videodevice.cpp +++ b/src/libcamera/v4l2_videodevice.cpp @@ -18,7 +18,6 @@ #include #include -#include #include #include @@ -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 dae3cb9f..d1dad2a0 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; -- cgit v1.2.1