From patchwork Wed Aug 24 16:24:21 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Umang Jain X-Patchwork-Id: 17196 X-Patchwork-Delegate: umang.jain@ideasonboard.com Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id A6D0DC3272 for ; Wed, 24 Aug 2022 16:24:41 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 7340F61FC6; Wed, 24 Aug 2022 18:24:41 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1661358281; bh=X5ZpqRFDht5x/EbcVssn9BdJntD9iFERZb7xAp2vsG4=; h=To:Date:In-Reply-To:References:Subject:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To: From; b=lLykAQYkWuqgVfyxY6fGVzjOKBE+3CQ516yad+X41Z3d4psWcM4TOLL/oRZdtFzXq QrxAUZjGKWqRUZPvQrOLA3TaXgSZGfYqHWv2VPvK2E/OO0Azhd+nRKhAqNXYd+H5iF QXFHMS6gqkyVHcPyyu+p4WS42jTemdHOIZHnPK7gcXspyEug0i6xGaW1b5MRE4wRYw hSo9W5gIbcSTJCQHPMKDUxL8OfH8GcdG+lON1ayumagksWtL5z3PyeQQNaAovdzmAU 7OKGJVyxCHurwD/gihoyQ1mIAnT1eXQkTE00rgPyD2SkasWHo3Nib1HtxasHQoRrAc yAyAwM55JT2vg== Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 58C1D60E26 for ; Wed, 24 Aug 2022 18:24:40 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="sZOL0Y9q"; dkim-atps=neutral Received: from umang.jainideasonboard.com (unknown [IPv6:2401:4900:1f3f:806e:6647:8e5c:f441:ca9a]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 4AC892B3; Wed, 24 Aug 2022 18:24:39 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1661358280; bh=X5ZpqRFDht5x/EbcVssn9BdJntD9iFERZb7xAp2vsG4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=sZOL0Y9qDmbIcBppalAf/VoN89P09KrMWYLCDCP1ejxBbfAfWxkmyuqn77k5txQah U8uH4UnVc5xxQA8u3F6/11HLMrLifMZ52DWc00vyn3KQOhJpIdGDagdruh/yuempT8 9f5HZgj3LsqOBa95flc6ltUF8hxtLB/oUPkcyS10= To: libcamera-devel Date: Wed, 24 Aug 2022 21:54:21 +0530 Message-Id: <20220824162425.71087-3-umang.jain@ideasonboard.com> X-Mailer: git-send-email 2.37.2 In-Reply-To: <20220824162425.71087-1-umang.jain@ideasonboard.com> References: <20220824162425.71087-1-umang.jain@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v2 2/6] libcamera: v4l2_device: Adjust colorspace if pixel format is RGB X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Umang Jain via libcamera-devel From: Umang Jain Reply-To: Umang Jain Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" The V4L2_COLORSPACE_SRGB colorspace maps to ColorSpace::Srgb. This is wrong as the V4L2_COLORSPACE_SRGB is ill-defined (defines Rec 601 Y'CbCr encoding and limited range) in the kernel. The RGB pixel formats should not use any Y'CbCr encoding and is always full range. Adjust the colorspace before reporting back to the userspace in such a situation. Moving forwards, the ColorSpace::Srgb will be defined in the true sense for RGB pixel formats. Signed-off-by: Umang Jain --- include/libcamera/internal/v4l2_device.h | 5 ++++- src/libcamera/v4l2_device.cpp | 19 +++++++++++++++---- src/libcamera/v4l2_subdevice.cpp | 10 ++++++++-- src/libcamera/v4l2_videodevice.cpp | 12 ++++++++---- 4 files changed, 35 insertions(+), 11 deletions(-) diff --git a/include/libcamera/internal/v4l2_device.h b/include/libcamera/internal/v4l2_device.h index a52a5f2c..5ae2ef8a 100644 --- a/include/libcamera/internal/v4l2_device.h +++ b/include/libcamera/internal/v4l2_device.h @@ -22,6 +22,8 @@ #include #include +#include "libcamera/internal/formats.h" + namespace libcamera { class EventNotifier; @@ -59,7 +61,8 @@ protected: int fd() const { return fd_.get(); } template - static std::optional toColorSpace(const T &v4l2Format); + static std::optional toColorSpace(const T &v4l2Format, + const PixelFormatInfo::ColourEncoding &colourEncoding); template static int fromColorSpace(const std::optional &colorSpace, T &v4l2Format); diff --git a/src/libcamera/v4l2_device.cpp b/src/libcamera/v4l2_device.cpp index b22a981f..1fb08b9d 100644 --- a/src/libcamera/v4l2_device.cpp +++ b/src/libcamera/v4l2_device.cpp @@ -24,6 +24,7 @@ #include #include +#include "libcamera/internal/formats.h" #include "libcamera/internal/sysfs.h" /** @@ -816,7 +817,8 @@ static const std::map rangeToV4l2 = { * \retval std::nullopt One or more V4L2 color space fields were not recognised */ template -std::optional V4L2Device::toColorSpace(const T &v4l2Format) +std::optional V4L2Device::toColorSpace(const T &v4l2Format, + const PixelFormatInfo::ColourEncoding &colourEncoding) { auto itColor = v4l2ToColorSpace.find(v4l2Format.colorspace); if (itColor == v4l2ToColorSpace.end()) @@ -839,6 +841,9 @@ std::optional V4L2Device::toColorSpace(const T &v4l2Format) return std::nullopt; colorSpace.ycbcrEncoding = itYcbcrEncoding->second; + + if (colourEncoding == PixelFormatInfo::ColourEncodingRGB) + colorSpace.ycbcrEncoding = ColorSpace::YcbcrEncoding::None; } if (v4l2Format.quantization != V4L2_QUANTIZATION_DEFAULT) { @@ -847,14 +852,20 @@ std::optional V4L2Device::toColorSpace(const T &v4l2Format) return std::nullopt; colorSpace.range = itRange->second; + + if (colourEncoding == PixelFormatInfo::ColourEncodingRGB) + colorSpace.range = ColorSpace::Range::Full; } return colorSpace; } -template std::optional V4L2Device::toColorSpace(const struct v4l2_pix_format &); -template std::optional V4L2Device::toColorSpace(const struct v4l2_pix_format_mplane &); -template std::optional V4L2Device::toColorSpace(const struct v4l2_mbus_framefmt &); +template std::optional V4L2Device::toColorSpace(const struct v4l2_pix_format &, + const PixelFormatInfo::ColourEncoding &); +template std::optional V4L2Device::toColorSpace(const struct v4l2_pix_format_mplane &, + const PixelFormatInfo::ColourEncoding &); +template std::optional V4L2Device::toColorSpace(const struct v4l2_mbus_framefmt &, + const PixelFormatInfo::ColourEncoding &); /** * \brief Fill in the color space fields of a V4L2 format from a ColorSpace diff --git a/src/libcamera/v4l2_subdevice.cpp b/src/libcamera/v4l2_subdevice.cpp index ab74b9f0..a52c414f 100644 --- a/src/libcamera/v4l2_subdevice.cpp +++ b/src/libcamera/v4l2_subdevice.cpp @@ -502,7 +502,10 @@ int V4L2Subdevice::getFormat(unsigned int pad, V4L2SubdeviceFormat *format, format->size.width = subdevFmt.format.width; format->size.height = subdevFmt.format.height; format->mbus_code = subdevFmt.format.code; - format->colorSpace = toColorSpace(subdevFmt.format); + auto iter = formatInfoMap.find(format->mbus_code); + if (iter == formatInfoMap.end()) + return -EINVAL; + format->colorSpace = toColorSpace(subdevFmt.format, iter->second.colourEncoding); return 0; } @@ -548,7 +551,10 @@ int V4L2Subdevice::setFormat(unsigned int pad, V4L2SubdeviceFormat *format, format->size.width = subdevFmt.format.width; format->size.height = subdevFmt.format.height; format->mbus_code = subdevFmt.format.code; - format->colorSpace = toColorSpace(subdevFmt.format); + auto iter = formatInfoMap.find(format->mbus_code); + if (iter == formatInfoMap.end()) + return -EINVAL; + format->colorSpace = toColorSpace(subdevFmt.format, iter->second.colourEncoding); return 0; } diff --git a/src/libcamera/v4l2_videodevice.cpp b/src/libcamera/v4l2_videodevice.cpp index 5a2d0e5b..0e3f5436 100644 --- a/src/libcamera/v4l2_videodevice.cpp +++ b/src/libcamera/v4l2_videodevice.cpp @@ -931,7 +931,8 @@ int V4L2VideoDevice::getFormatMultiplane(V4L2DeviceFormat *format) format->size.height = pix->height; format->fourcc = V4L2PixelFormat(pix->pixelformat); format->planesCount = pix->num_planes; - format->colorSpace = toColorSpace(*pix); + format->colorSpace = + toColorSpace(*pix, PixelFormatInfo::info(format->fourcc).colourEncoding); for (unsigned int i = 0; i < format->planesCount; ++i) { format->planes[i].bpl = pix->plane_fmt[i].bytesperline; @@ -987,7 +988,8 @@ int V4L2VideoDevice::trySetFormatMultiplane(V4L2DeviceFormat *format, bool set) format->planes[i].bpl = pix->plane_fmt[i].bytesperline; format->planes[i].size = pix->plane_fmt[i].sizeimage; } - format->colorSpace = toColorSpace(*pix); + format->colorSpace = + toColorSpace(*pix, PixelFormatInfo::info(format->fourcc).colourEncoding); return 0; } @@ -1011,7 +1013,8 @@ int V4L2VideoDevice::getFormatSingleplane(V4L2DeviceFormat *format) format->planesCount = 1; format->planes[0].bpl = pix->bytesperline; format->planes[0].size = pix->sizeimage; - format->colorSpace = toColorSpace(*pix); + format->colorSpace = + toColorSpace(*pix, PixelFormatInfo::info(format->fourcc).colourEncoding); return 0; } @@ -1053,7 +1056,8 @@ int V4L2VideoDevice::trySetFormatSingleplane(V4L2DeviceFormat *format, bool set) format->planesCount = 1; format->planes[0].bpl = pix->bytesperline; format->planes[0].size = pix->sizeimage; - format->colorSpace = toColorSpace(*pix); + format->colorSpace = + toColorSpace(*pix, PixelFormatInfo::info(format->fourcc).colourEncoding); return 0; }