From patchwork Mon Aug 29 16:37:36 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Umang Jain X-Patchwork-Id: 17228 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 72936C3272 for ; Mon, 29 Aug 2022 16:38:05 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 2D3E061FC4; Mon, 29 Aug 2022 18:38:05 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1661791085; bh=aVLEkdTdCQbwkxIP+puXQtQhFUIios9iTgOsZdYyiZs=; 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=KNudnC29f7Oi8LmfiazVRd6dPx9hQSMTVoPpSFtuEqzKJK1zHsb1aDQGHZASCL0OV UVRXoEE+tAtRzUaj80/+ABFlUmLbBxEXSTu7z/I8tioxj/D5eZwP6CEdoQ0X3/ZWUX V3FyJHWoAVNHxhyvkNVPOr/l8Bmawaa1nBKCLz6iZOCQefHADnipFjpqa+xCP0HY8f aWQEPm8JgpRoNbelmOwg57t6voaw+bPHrGUYEmqE7SprpkWptnymtAx+PIhxJyn2Aq mSWtIF8zf+ukLNKGRmdBCuiDEOm9LIqx9v0wkORpTTySLQAqzd4K3CwC61KHsL8g3u YOvWINSpP13KA== Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 59C2761FBE for ; Mon, 29 Aug 2022 18:38:03 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="OorqfZgo"; dkim-atps=neutral Received: from umang.jainideasonboard.com (unknown [IPv6:2401:4900:1f3f:1548:78ac:4a3:edc3:c28a]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 191A1505; Mon, 29 Aug 2022 18:38:01 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1661791083; bh=aVLEkdTdCQbwkxIP+puXQtQhFUIios9iTgOsZdYyiZs=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=OorqfZgoowvJCE8w60/WHRV7ObDitWFFeVD0pP54yB8Ukk9xW9OMHKutbs78Bp7TH C4FiTI0QRmgygvwj4nqQpTRIjetVQprGtvAuJ1GFphzNowGLCLGkRCwMR3DWNzY+SQ ww5e38xQaQFoa51JHaGnzqTMwc8AcWoD1vZAS8NI= To: libcamera-devel@lists.libcamera.org Date: Mon, 29 Aug 2022 22:07:36 +0530 Message-Id: <20220829163742.1006102-2-umang.jain@ideasonboard.com> X-Mailer: git-send-email 2.37.2 In-Reply-To: <20220829163742.1006102-1-umang.jain@ideasonboard.com> References: <20220829163742.1006102-1-umang.jain@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v3 1/7] libcamera: v4l2_subdevice: Add color encoding for media bus formats 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" Signed-off-by: Umang Jain Reviewed-by: Laurent Pinchart --- src/libcamera/v4l2_subdevice.cpp | 154 ++++++++++++++++--------------- 1 file changed, 79 insertions(+), 75 deletions(-) diff --git a/src/libcamera/v4l2_subdevice.cpp b/src/libcamera/v4l2_subdevice.cpp index d8fd92e3..07a0bb07 100644 --- a/src/libcamera/v4l2_subdevice.cpp +++ b/src/libcamera/v4l2_subdevice.cpp @@ -23,6 +23,7 @@ #include #include +#include "libcamera/internal/formats.h" #include "libcamera/internal/media_device.h" #include "libcamera/internal/media_object.h" @@ -42,10 +43,12 @@ namespace { * \brief Information about media bus formats * \param bitsPerPixel Bits per pixel * \param name Name of MBUS format + * \param colourEncoding Type of colour encoding */ struct V4L2SubdeviceFormatInfo { unsigned int bitsPerPixel; const char *name; + PixelFormatInfo::ColourEncoding colourEncoding; }; /* @@ -54,81 +57,82 @@ struct V4L2SubdeviceFormatInfo { * bus codes */ const std::map formatInfoMap = { - { MEDIA_BUS_FMT_RGB444_2X8_PADHI_BE, { 16, "RGB444_2X8_PADHI_BE" } }, - { MEDIA_BUS_FMT_RGB444_2X8_PADHI_LE, { 16, "RGB444_2X8_PADHI_LE" } }, - { MEDIA_BUS_FMT_RGB555_2X8_PADHI_BE, { 16, "RGB555_2X8_PADHI_BE" } }, - { MEDIA_BUS_FMT_RGB555_2X8_PADHI_LE, { 16, "RGB555_2X8_PADHI_LE" } }, - { MEDIA_BUS_FMT_RGB565_1X16, { 16, "RGB565_1X16" } }, - { MEDIA_BUS_FMT_BGR565_2X8_BE, { 16, "BGR565_2X8_BE" } }, - { MEDIA_BUS_FMT_BGR565_2X8_LE, { 16, "BGR565_2X8_LE" } }, - { MEDIA_BUS_FMT_RGB565_2X8_BE, { 16, "RGB565_2X8_BE" } }, - { MEDIA_BUS_FMT_RGB565_2X8_LE, { 16, "RGB565_2X8_LE" } }, - { MEDIA_BUS_FMT_RGB666_1X18, { 18, "RGB666_1X18" } }, - { MEDIA_BUS_FMT_RGB888_1X24, { 24, "RGB888_1X24" } }, - { MEDIA_BUS_FMT_RGB888_2X12_BE, { 24, "RGB888_2X12_BE" } }, - { MEDIA_BUS_FMT_RGB888_2X12_LE, { 24, "RGB888_2X12_LE" } }, - { MEDIA_BUS_FMT_ARGB8888_1X32, { 32, "ARGB8888_1X32" } }, - { MEDIA_BUS_FMT_Y8_1X8, { 8, "Y8_1X8" } }, - { MEDIA_BUS_FMT_UV8_1X8, { 8, "UV8_1X8" } }, - { MEDIA_BUS_FMT_UYVY8_1_5X8, { 12, "UYVY8_1_5X8" } }, - { MEDIA_BUS_FMT_VYUY8_1_5X8, { 12, "VYUY8_1_5X8" } }, - { MEDIA_BUS_FMT_YUYV8_1_5X8, { 12, "YUYV8_1_5X8" } }, - { MEDIA_BUS_FMT_YVYU8_1_5X8, { 12, "YVYU8_1_5X8" } }, - { MEDIA_BUS_FMT_UYVY8_2X8, { 16, "UYVY8_2X8" } }, - { MEDIA_BUS_FMT_VYUY8_2X8, { 16, "VYUY8_2X8" } }, - { MEDIA_BUS_FMT_YUYV8_2X8, { 16, "YUYV8_2X8" } }, - { MEDIA_BUS_FMT_YVYU8_2X8, { 16, "YVYU8_2X8" } }, - { MEDIA_BUS_FMT_Y10_1X10, { 10, "Y10_1X10" } }, - { MEDIA_BUS_FMT_UYVY10_2X10, { 20, "UYVY10_2X10" } }, - { MEDIA_BUS_FMT_VYUY10_2X10, { 20, "VYUY10_2X10" } }, - { MEDIA_BUS_FMT_YUYV10_2X10, { 20, "YUYV10_2X10" } }, - { MEDIA_BUS_FMT_YVYU10_2X10, { 20, "YVYU10_2X10" } }, - { MEDIA_BUS_FMT_Y12_1X12, { 12, "Y12_1X12" } }, - { MEDIA_BUS_FMT_UYVY8_1X16, { 16, "UYVY8_1X16" } }, - { MEDIA_BUS_FMT_VYUY8_1X16, { 16, "VYUY8_1X16" } }, - { MEDIA_BUS_FMT_YUYV8_1X16, { 16, "YUYV8_1X16" } }, - { MEDIA_BUS_FMT_YVYU8_1X16, { 16, "YVYU8_1X16" } }, - { MEDIA_BUS_FMT_YDYUYDYV8_1X16, { 16, "YDYUYDYV8_1X16" } }, - { MEDIA_BUS_FMT_UYVY10_1X20, { 20, "UYVY10_1X20" } }, - { MEDIA_BUS_FMT_VYUY10_1X20, { 20, "VYUY10_1X20" } }, - { MEDIA_BUS_FMT_YUYV10_1X20, { 20, "YUYV10_1X20" } }, - { MEDIA_BUS_FMT_YVYU10_1X20, { 20, "YVYU10_1X20" } }, - { MEDIA_BUS_FMT_YUV8_1X24, { 24, "YUV8_1X24" } }, - { MEDIA_BUS_FMT_YUV10_1X30, { 30, "YUV10_1X30" } }, - { MEDIA_BUS_FMT_AYUV8_1X32, { 32, "AYUV8_1X32" } }, - { MEDIA_BUS_FMT_UYVY12_2X12, { 24, "UYVY12_2X12" } }, - { MEDIA_BUS_FMT_VYUY12_2X12, { 24, "VYUY12_2X12" } }, - { MEDIA_BUS_FMT_YUYV12_2X12, { 24, "YUYV12_2X12" } }, - { MEDIA_BUS_FMT_YVYU12_2X12, { 24, "YVYU12_2X12" } }, - { MEDIA_BUS_FMT_UYVY12_1X24, { 24, "UYVY12_1X24" } }, - { MEDIA_BUS_FMT_VYUY12_1X24, { 24, "VYUY12_1X24" } }, - { MEDIA_BUS_FMT_YUYV12_1X24, { 24, "YUYV12_1X24" } }, - { MEDIA_BUS_FMT_YVYU12_1X24, { 24, "YVYU12_1X24" } }, - { MEDIA_BUS_FMT_SBGGR8_1X8, { 8, "SBGGR8_1X8" } }, - { MEDIA_BUS_FMT_SGBRG8_1X8, { 8, "SGBRG8_1X8" } }, - { MEDIA_BUS_FMT_SGRBG8_1X8, { 8, "SGRBG8_1X8" } }, - { MEDIA_BUS_FMT_SRGGB8_1X8, { 8, "SRGGB8_1X8" } }, - { MEDIA_BUS_FMT_SBGGR10_ALAW8_1X8, { 8, "SBGGR10_ALAW8_1X8" } }, - { MEDIA_BUS_FMT_SGBRG10_ALAW8_1X8, { 8, "SGBRG10_ALAW8_1X8" } }, - { MEDIA_BUS_FMT_SGRBG10_ALAW8_1X8, { 8, "SGRBG10_ALAW8_1X8" } }, - { MEDIA_BUS_FMT_SRGGB10_ALAW8_1X8, { 8, "SRGGB10_ALAW8_1X8" } }, - { MEDIA_BUS_FMT_SBGGR10_DPCM8_1X8, { 8, "SBGGR10_DPCM8_1X8" } }, - { MEDIA_BUS_FMT_SGBRG10_DPCM8_1X8, { 8, "SGBRG10_DPCM8_1X8" } }, - { MEDIA_BUS_FMT_SGRBG10_DPCM8_1X8, { 8, "SGRBG10_DPCM8_1X8" } }, - { MEDIA_BUS_FMT_SRGGB10_DPCM8_1X8, { 8, "SRGGB10_DPCM8_1X8" } }, - { MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_BE, { 16, "SBGGR10_2X8_PADHI_BE" } }, - { MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_LE, { 16, "SBGGR10_2X8_PADHI_LE" } }, - { MEDIA_BUS_FMT_SBGGR10_2X8_PADLO_BE, { 16, "SBGGR10_2X8_PADLO_BE" } }, - { MEDIA_BUS_FMT_SBGGR10_2X8_PADLO_LE, { 16, "SBGGR10_2X8_PADLO_LE" } }, - { MEDIA_BUS_FMT_SBGGR10_1X10, { 10, "SBGGR10_1X10" } }, - { MEDIA_BUS_FMT_SGBRG10_1X10, { 10, "SGBRG10_1X10" } }, - { MEDIA_BUS_FMT_SGRBG10_1X10, { 10, "SGRBG10_1X10" } }, - { MEDIA_BUS_FMT_SRGGB10_1X10, { 10, "SRGGB10_1X10" } }, - { MEDIA_BUS_FMT_SBGGR12_1X12, { 12, "SBGGR12_1X12" } }, - { MEDIA_BUS_FMT_SGBRG12_1X12, { 12, "SGBRG12_1X12" } }, - { MEDIA_BUS_FMT_SGRBG12_1X12, { 12, "SGRBG12_1X12" } }, - { MEDIA_BUS_FMT_SRGGB12_1X12, { 12, "SRGGB12_1X12" } }, - { MEDIA_BUS_FMT_AHSV8888_1X32, { 32, "AHSV8888_1X32" } }, + { MEDIA_BUS_FMT_RGB444_2X8_PADHI_BE, { 16, "RGB444_2X8_PADHI_BE", PixelFormatInfo::ColourEncodingRGB } }, + { MEDIA_BUS_FMT_RGB444_2X8_PADHI_LE, { 16, "RGB444_2X8_PADHI_LE", PixelFormatInfo::ColourEncodingRGB } }, + { MEDIA_BUS_FMT_RGB555_2X8_PADHI_BE, { 16, "RGB555_2X8_PADHI_BE", PixelFormatInfo::ColourEncodingRGB } }, + { MEDIA_BUS_FMT_RGB555_2X8_PADHI_LE, { 16, "RGB555_2X8_PADHI_LE", PixelFormatInfo::ColourEncodingRGB } }, + { MEDIA_BUS_FMT_RGB565_1X16, { 16, "RGB565_1X16", PixelFormatInfo::ColourEncodingRGB } }, + { MEDIA_BUS_FMT_BGR565_2X8_BE, { 16, "BGR565_2X8_BE", PixelFormatInfo::ColourEncodingRGB } }, + { MEDIA_BUS_FMT_BGR565_2X8_LE, { 16, "BGR565_2X8_LE", PixelFormatInfo::ColourEncodingRGB } }, + { MEDIA_BUS_FMT_RGB565_2X8_BE, { 16, "RGB565_2X8_BE", PixelFormatInfo::ColourEncodingRGB } }, + { MEDIA_BUS_FMT_RGB565_2X8_LE, { 16, "RGB565_2X8_LE", PixelFormatInfo::ColourEncodingRGB } }, + { MEDIA_BUS_FMT_RGB666_1X18, { 18, "RGB666_1X18", PixelFormatInfo::ColourEncodingRGB } }, + { MEDIA_BUS_FMT_RGB888_1X24, { 24, "RGB888_1X24", PixelFormatInfo::ColourEncodingRGB } }, + { MEDIA_BUS_FMT_RGB888_2X12_BE, { 24, "RGB888_2X12_BE", PixelFormatInfo::ColourEncodingRGB } }, + { MEDIA_BUS_FMT_RGB888_2X12_LE, { 24, "RGB888_2X12_LE", PixelFormatInfo::ColourEncodingRGB } }, + { MEDIA_BUS_FMT_ARGB8888_1X32, { 32, "ARGB8888_1X32", PixelFormatInfo::ColourEncodingRGB } }, + { MEDIA_BUS_FMT_Y8_1X8, { 8, "Y8_1X8", PixelFormatInfo::ColourEncodingYUV } }, + { MEDIA_BUS_FMT_UV8_1X8, { 8, "UV8_1X8", PixelFormatInfo::ColourEncodingYUV } }, + { MEDIA_BUS_FMT_UYVY8_1_5X8, { 12, "UYVY8_1_5X8", PixelFormatInfo::ColourEncodingYUV } }, + { MEDIA_BUS_FMT_VYUY8_1_5X8, { 12, "VYUY8_1_5X8", PixelFormatInfo::ColourEncodingYUV } }, + { MEDIA_BUS_FMT_YUYV8_1_5X8, { 12, "YUYV8_1_5X8", PixelFormatInfo::ColourEncodingYUV } }, + { MEDIA_BUS_FMT_YVYU8_1_5X8, { 12, "YVYU8_1_5X8", PixelFormatInfo::ColourEncodingYUV } }, + { MEDIA_BUS_FMT_UYVY8_2X8, { 16, "UYVY8_2X8", PixelFormatInfo::ColourEncodingYUV } }, + { MEDIA_BUS_FMT_VYUY8_2X8, { 16, "VYUY8_2X8", PixelFormatInfo::ColourEncodingYUV } }, + { MEDIA_BUS_FMT_YUYV8_2X8, { 16, "YUYV8_2X8", PixelFormatInfo::ColourEncodingYUV } }, + { MEDIA_BUS_FMT_YVYU8_2X8, { 16, "YVYU8_2X8", PixelFormatInfo::ColourEncodingYUV } }, + { MEDIA_BUS_FMT_Y10_1X10, { 10, "Y10_1X10", PixelFormatInfo::ColourEncodingYUV } }, + { MEDIA_BUS_FMT_UYVY10_2X10, { 20, "UYVY10_2X10", PixelFormatInfo::ColourEncodingYUV } }, + { MEDIA_BUS_FMT_VYUY10_2X10, { 20, "VYUY10_2X10", PixelFormatInfo::ColourEncodingYUV } }, + { MEDIA_BUS_FMT_YUYV10_2X10, { 20, "YUYV10_2X10", PixelFormatInfo::ColourEncodingYUV } }, + { MEDIA_BUS_FMT_YVYU10_2X10, { 20, "YVYU10_2X10", PixelFormatInfo::ColourEncodingYUV } }, + { MEDIA_BUS_FMT_Y12_1X12, { 12, "Y12_1X12", PixelFormatInfo::ColourEncodingYUV } }, + { MEDIA_BUS_FMT_UYVY8_1X16, { 16, "UYVY8_1X16", PixelFormatInfo::ColourEncodingYUV } }, + { MEDIA_BUS_FMT_VYUY8_1X16, { 16, "VYUY8_1X16", PixelFormatInfo::ColourEncodingYUV } }, + { MEDIA_BUS_FMT_YUYV8_1X16, { 16, "YUYV8_1X16", PixelFormatInfo::ColourEncodingYUV } }, + { MEDIA_BUS_FMT_YVYU8_1X16, { 16, "YVYU8_1X16", PixelFormatInfo::ColourEncodingYUV } }, + { MEDIA_BUS_FMT_YDYUYDYV8_1X16, { 16, "YDYUYDYV8_1X16", PixelFormatInfo::ColourEncodingYUV } }, + { MEDIA_BUS_FMT_UYVY10_1X20, { 20, "UYVY10_1X20", PixelFormatInfo::ColourEncodingYUV } }, + { MEDIA_BUS_FMT_VYUY10_1X20, { 20, "VYUY10_1X20", PixelFormatInfo::ColourEncodingYUV } }, + { MEDIA_BUS_FMT_YUYV10_1X20, { 20, "YUYV10_1X20", PixelFormatInfo::ColourEncodingYUV } }, + { MEDIA_BUS_FMT_YVYU10_1X20, { 20, "YVYU10_1X20", PixelFormatInfo::ColourEncodingYUV } }, + { MEDIA_BUS_FMT_YUV8_1X24, { 24, "YUV8_1X24", PixelFormatInfo::ColourEncodingYUV } }, + { MEDIA_BUS_FMT_YUV10_1X30, { 30, "YUV10_1X30", PixelFormatInfo::ColourEncodingYUV } }, + { MEDIA_BUS_FMT_AYUV8_1X32, { 32, "AYUV8_1X32", PixelFormatInfo::ColourEncodingYUV } }, + { MEDIA_BUS_FMT_UYVY12_2X12, { 24, "UYVY12_2X12", PixelFormatInfo::ColourEncodingYUV } }, + { MEDIA_BUS_FMT_VYUY12_2X12, { 24, "VYUY12_2X12", PixelFormatInfo::ColourEncodingYUV } }, + { MEDIA_BUS_FMT_YUYV12_2X12, { 24, "YUYV12_2X12", PixelFormatInfo::ColourEncodingYUV } }, + { MEDIA_BUS_FMT_YVYU12_2X12, { 24, "YVYU12_2X12", PixelFormatInfo::ColourEncodingYUV } }, + { MEDIA_BUS_FMT_UYVY12_1X24, { 24, "UYVY12_1X24", PixelFormatInfo::ColourEncodingYUV } }, + { MEDIA_BUS_FMT_VYUY12_1X24, { 24, "VYUY12_1X24", PixelFormatInfo::ColourEncodingYUV } }, + { MEDIA_BUS_FMT_YUYV12_1X24, { 24, "YUYV12_1X24", PixelFormatInfo::ColourEncodingYUV } }, + { MEDIA_BUS_FMT_YVYU12_1X24, { 24, "YVYU12_1X24", PixelFormatInfo::ColourEncodingYUV } }, + { MEDIA_BUS_FMT_SBGGR8_1X8, { 8, "SBGGR8_1X8", PixelFormatInfo::ColourEncodingRAW } }, + { MEDIA_BUS_FMT_SGBRG8_1X8, { 8, "SGBRG8_1X8", PixelFormatInfo::ColourEncodingRAW } }, + { MEDIA_BUS_FMT_SGRBG8_1X8, { 8, "SGRBG8_1X8", PixelFormatInfo::ColourEncodingRAW } }, + { MEDIA_BUS_FMT_SRGGB8_1X8, { 8, "SRGGB8_1X8", PixelFormatInfo::ColourEncodingRAW } }, + { MEDIA_BUS_FMT_SBGGR10_ALAW8_1X8, { 8, "SBGGR10_ALAW8_1X8", PixelFormatInfo::ColourEncodingRAW } }, + { MEDIA_BUS_FMT_SGBRG10_ALAW8_1X8, { 8, "SGBRG10_ALAW8_1X8", PixelFormatInfo::ColourEncodingRAW } }, + { MEDIA_BUS_FMT_SGRBG10_ALAW8_1X8, { 8, "SGRBG10_ALAW8_1X8", PixelFormatInfo::ColourEncodingRAW } }, + { MEDIA_BUS_FMT_SRGGB10_ALAW8_1X8, { 8, "SRGGB10_ALAW8_1X8", PixelFormatInfo::ColourEncodingRAW } }, + { MEDIA_BUS_FMT_SBGGR10_DPCM8_1X8, { 8, "SBGGR10_DPCM8_1X8", PixelFormatInfo::ColourEncodingRAW } }, + { MEDIA_BUS_FMT_SGBRG10_DPCM8_1X8, { 8, "SGBRG10_DPCM8_1X8", PixelFormatInfo::ColourEncodingRAW } }, + { MEDIA_BUS_FMT_SGRBG10_DPCM8_1X8, { 8, "SGRBG10_DPCM8_1X8", PixelFormatInfo::ColourEncodingRAW } }, + { MEDIA_BUS_FMT_SRGGB10_DPCM8_1X8, { 8, "SRGGB10_DPCM8_1X8", PixelFormatInfo::ColourEncodingRAW } }, + { MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_BE, { 16, "SBGGR10_2X8_PADHI_BE", PixelFormatInfo::ColourEncodingRAW } }, + { MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_LE, { 16, "SBGGR10_2X8_PADHI_LE", PixelFormatInfo::ColourEncodingRAW } }, + { MEDIA_BUS_FMT_SBGGR10_2X8_PADLO_BE, { 16, "SBGGR10_2X8_PADLO_BE", PixelFormatInfo::ColourEncodingRAW } }, + { MEDIA_BUS_FMT_SBGGR10_2X8_PADLO_LE, { 16, "SBGGR10_2X8_PADLO_LE", PixelFormatInfo::ColourEncodingRAW } }, + { MEDIA_BUS_FMT_SBGGR10_1X10, { 10, "SBGGR10_1X10", PixelFormatInfo::ColourEncodingRAW } }, + { MEDIA_BUS_FMT_SGBRG10_1X10, { 10, "SGBRG10_1X10", PixelFormatInfo::ColourEncodingRAW } }, + { MEDIA_BUS_FMT_SGRBG10_1X10, { 10, "SGRBG10_1X10", PixelFormatInfo::ColourEncodingRAW } }, + { MEDIA_BUS_FMT_SRGGB10_1X10, { 10, "SRGGB10_1X10", PixelFormatInfo::ColourEncodingRAW } }, + { MEDIA_BUS_FMT_SBGGR12_1X12, { 12, "SBGGR12_1X12", PixelFormatInfo::ColourEncodingRAW } }, + { MEDIA_BUS_FMT_SGBRG12_1X12, { 12, "SGBRG12_1X12", PixelFormatInfo::ColourEncodingRAW } }, + { MEDIA_BUS_FMT_SGRBG12_1X12, { 12, "SGRBG12_1X12", PixelFormatInfo::ColourEncodingRAW } }, + { MEDIA_BUS_FMT_SRGGB12_1X12, { 12, "SRGGB12_1X12", PixelFormatInfo::ColourEncodingRAW } }, + /* \todo Clarify colour encoding for HSV formats */ + { MEDIA_BUS_FMT_AHSV8888_1X32, { 32, "AHSV8888_1X32", PixelFormatInfo::ColourEncodingRGB } }, }; } /* namespace */ From patchwork Mon Aug 29 16:37:37 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Umang Jain X-Patchwork-Id: 17229 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 20E92C3272 for ; Mon, 29 Aug 2022 16:38:08 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id CF97F61FC8; Mon, 29 Aug 2022 18:38:07 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1661791087; bh=ujuqE6ma3HkGef1NirHTwKRyN2252ckQIpdhAhMr73Y=; 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=dF8wCsF4jH3zk8WMLlCdQVfZWdNE4fg6SEzkUrBLy15h0OdCv4VGiM/WXYHZ+/kOH umWr0V8n4ACE7jv0Q6+AMpyMA1BUmfsXqZRC88+dNQBpQn/rM74V+MqCBi8f0ax67N rwtF50ykuGumK49reF6jfSzDRJPToayDH5ESNBy8wRe66eyJrfWyekNmhYOf9c4zh1 bYu+GfqYO7c1YkORU8Cph0dE14t6Hd0hNcgniehr8Hd7sA8FCuVZ6oJvLJXcNeUZEF Elog/E8SckUwPprYmxDfNqQ9RQmjt4aCX4s5GyYp5RG5M7gfE3vpM4Vo8cfjTKNPmc 3tO0OquC8XGAQ== Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 3826C61FC5 for ; Mon, 29 Aug 2022 18:38:05 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="Pth+zvDh"; dkim-atps=neutral Received: from umang.jainideasonboard.com (unknown [IPv6:2401:4900:1f3f:1548:78ac:4a3:edc3:c28a]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 2472A8BD; Mon, 29 Aug 2022 18:38:03 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1661791084; bh=ujuqE6ma3HkGef1NirHTwKRyN2252ckQIpdhAhMr73Y=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Pth+zvDhn1pE//1sOYqrKdGSpLrF0GAUWPUMHOTLovNYJq6yLDZEp8pRJ8mnfx73+ Jb/nqcpJRVVqKzcuTMtTxbxrnhxneZFoyDMou+NLnujZg0P6QhIlf+yJOSO6O7hpD+ h7tlXPCS1QPbcIuAvDgLJYpkf17dIHwqX0PeUcnw= To: libcamera-devel@lists.libcamera.org Date: Mon, 29 Aug 2022 22:07:37 +0530 Message-Id: <20220829163742.1006102-3-umang.jain@ideasonboard.com> X-Mailer: git-send-email 2.37.2 In-Reply-To: <20220829163742.1006102-1-umang.jain@ideasonboard.com> References: <20220829163742.1006102-1-umang.jain@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v3 2/7] libcamera: v4l2_device: Adjust colorspace based on pixel format 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" V4L2 has no "none" YCbCr encoding, and thus reports an encoding for all formats, including RGB and raw formats. This causes the libcamera ColorSpace to report incorrect encodings for non-YUV formats. Fix it by overriding the encoding reported by the kernel to YCbCrEncoding::None for non-YUV pixel formats and media bus formats. Similarly, override the quantization range of non-YUV formats to full range, as limited range isn't used for RGB and raw formats. Signed-off-by: Umang Jain Reviewed-by: Laurent Pinchart --- include/libcamera/internal/v4l2_device.h | 5 +++- src/libcamera/v4l2_device.cpp | 29 ++++++++++++++++++--- src/libcamera/v4l2_subdevice.cpp | 32 ++++++++++++++++++++++-- src/libcamera/v4l2_videodevice.cpp | 12 ++++++--- 4 files changed, 67 insertions(+), 11 deletions(-) diff --git a/include/libcamera/internal/v4l2_device.h b/include/libcamera/internal/v4l2_device.h index a52a5f2c..75304be1 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, + 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..301620f8 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" /** @@ -805,6 +806,7 @@ static const std::map rangeToV4l2 = { /** * \brief Convert the color space fields in a V4L2 format to a ColorSpace * \param[in] v4l2Format A V4L2 format containing color space information + * \param[in] colourEncoding Type of colour encoding * * The colorspace, ycbcr_enc, xfer_func and quantization fields within a * V4L2 format structure are converted to a corresponding ColorSpace. @@ -816,7 +818,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, + PixelFormatInfo::ColourEncoding colourEncoding) { auto itColor = v4l2ToColorSpace.find(v4l2Format.colorspace); if (itColor == v4l2ToColorSpace.end()) @@ -839,6 +842,14 @@ std::optional V4L2Device::toColorSpace(const T &v4l2Format) return std::nullopt; colorSpace.ycbcrEncoding = itYcbcrEncoding->second; + + /* + * V4L2 has no "none" encoding, override the value returned by + * the kernel for non-YUV formats as YCbCr encoding isn't + * applicable in that case. + */ + if (colourEncoding != PixelFormatInfo::ColourEncodingYUV) + colorSpace.ycbcrEncoding = ColorSpace::YcbcrEncoding::None; } if (v4l2Format.quantization != V4L2_QUANTIZATION_DEFAULT) { @@ -847,14 +858,24 @@ std::optional V4L2Device::toColorSpace(const T &v4l2Format) return std::nullopt; colorSpace.range = itRange->second; + + /* + * "Limited" quantization range is only meant for YUV formats. + * Override the range to "Full" for all other formats. + */ + if (colourEncoding != PixelFormatInfo::ColourEncodingYUV) + 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 &, + PixelFormatInfo::ColourEncoding); +template std::optional V4L2Device::toColorSpace(const struct v4l2_pix_format_mplane &, + PixelFormatInfo::ColourEncoding); +template std::optional V4L2Device::toColorSpace(const struct v4l2_mbus_framefmt &, + 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 07a0bb07..0389f1b3 100644 --- a/src/libcamera/v4l2_subdevice.cpp +++ b/src/libcamera/v4l2_subdevice.cpp @@ -502,8 +502,22 @@ int V4L2Subdevice::getFormat(unsigned int pad, V4L2SubdeviceFormat *format, format->size.width = subdevFmt.format.width; format->size.height = subdevFmt.format.height; + + PixelFormatInfo::ColourEncoding colourEncoding; + auto iter = formatInfoMap.find(subdevFmt.format.code); + if (iter != formatInfoMap.end()) { + colourEncoding = iter->second.colourEncoding; + } else { + LOG(V4L2, Warning) + << "Unknown subdev format " + << utils::hex(subdevFmt.format.code, 4) + << ", defaulting to RGB encoding"; + + colourEncoding = PixelFormatInfo::ColourEncodingRGB; + } + format->mbus_code = subdevFmt.format.code; - format->colorSpace = toColorSpace(subdevFmt.format); + format->colorSpace = toColorSpace(subdevFmt.format, colourEncoding); return 0; } @@ -548,8 +562,22 @@ int V4L2Subdevice::setFormat(unsigned int pad, V4L2SubdeviceFormat *format, format->size.width = subdevFmt.format.width; format->size.height = subdevFmt.format.height; + + PixelFormatInfo::ColourEncoding colourEncoding; + auto iter = formatInfoMap.find(subdevFmt.format.code); + if (iter != formatInfoMap.end()) { + colourEncoding = iter->second.colourEncoding; + } else { + LOG(V4L2, Warning) + << "Unknown subdev format " + << utils::hex(subdevFmt.format.code, 4) + << ", defaulting to RGB encoding"; + + colourEncoding = PixelFormatInfo::ColourEncodingRGB; + } + format->mbus_code = subdevFmt.format.code; - format->colorSpace = toColorSpace(subdevFmt.format); + format->colorSpace = toColorSpace(subdevFmt.format, 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; } From patchwork Mon Aug 29 16:37:38 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Umang Jain X-Patchwork-Id: 17230 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 973D7C3272 for ; Mon, 29 Aug 2022 16:38:10 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 4CE4361FCB; Mon, 29 Aug 2022 18:38:10 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1661791090; bh=acK2S0GxZrfhSb3ahOQmVL+wQKOTvIggEMmTpEK2VcY=; 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=iRyZV8WpNfhmYwAJfMgk20GBtPfD0lC/xr6w98X2LS6ec9GdYVgba/zfAaFzmSGnm t2eXe+A9nHGF6Z8GGpLaLdDDq5cM8sMfqeXFoqX7euqynEA5S1dw8SGTUlDoVRe8OU 5oNkQa2vGstu7u+NPLEQ2cIM/Alumfs+NcPopDNRXHTvdtvMDWTj9+UqQwFy+ZXJ9r H3QCazHgY8y2h7vp1T6wPXBCelGP+WAq3zLvYwLxO9RQz0o/Mm624DhS+0AT01HTbF K6tSDvoH6lxvcc8CNvlmQj8PiHxm9PS8qZwTo33zd6qw1IdQx+aYz15YxVRId4Ncio 5lQJjE+LNeAVg== Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 1D0FB61FBA for ; Mon, 29 Aug 2022 18:38:07 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="gmLarNg7"; dkim-atps=neutral Received: from umang.jainideasonboard.com (unknown [IPv6:2401:4900:1f3f:1548:78ac:4a3:edc3:c28a]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 1780B8BD; Mon, 29 Aug 2022 18:38:05 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1661791086; bh=acK2S0GxZrfhSb3ahOQmVL+wQKOTvIggEMmTpEK2VcY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=gmLarNg7PoGl2P/wIKobnpPw9NLYstOuruyoy/gllwp7j+kWs/9IAxYgCqTnsNf0l y9X4Vm0H3IfoH8EEVoewtveT5AXW4+vVFJWP+gcgCi2SS87iPNhq+sKg5ul8uHZoaq fcw/TxlyXUzRbkCetawA43oTaSmi+jel6uw9sX8g= To: libcamera-devel@lists.libcamera.org Date: Mon, 29 Aug 2022 22:07:38 +0530 Message-Id: <20220829163742.1006102-4-umang.jain@ideasonboard.com> X-Mailer: git-send-email 2.37.2 In-Reply-To: <20220829163742.1006102-1-umang.jain@ideasonboard.com> References: <20220829163742.1006102-1-umang.jain@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v3 3/7] libcamera: v4l2_videodevice: Improve toColorSpace() readability 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" Abstract out usage of V4L2Device::toColorspace() to a separate namespace. Since it is separated out in an unnamed namespace, the V4L2Device::toColorSpace() function needs to made public. This is not an issue since V4L2Device is an internal class. No functional changes intended. Signed-off-by: Umang Jain Reviewed-by: Laurent Pinchart --- include/libcamera/internal/v4l2_device.h | 14 +++++++------- src/libcamera/v4l2_videodevice.cpp | 23 +++++++++++++++-------- 2 files changed, 22 insertions(+), 15 deletions(-) diff --git a/include/libcamera/internal/v4l2_device.h b/include/libcamera/internal/v4l2_device.h index 75304be1..606332e1 100644 --- a/include/libcamera/internal/v4l2_device.h +++ b/include/libcamera/internal/v4l2_device.h @@ -49,6 +49,13 @@ public: void updateControlInfo(); + template + static std::optional toColorSpace(const T &v4l2Format, + PixelFormatInfo::ColourEncoding colourEncoding); + + template + static int fromColorSpace(const std::optional &colorSpace, T &v4l2Format); + protected: V4L2Device(const std::string &deviceNode); ~V4L2Device(); @@ -60,13 +67,6 @@ protected: int fd() const { return fd_.get(); } - template - static std::optional toColorSpace(const T &v4l2Format, - PixelFormatInfo::ColourEncoding colourEncoding); - - template - static int fromColorSpace(const std::optional &colorSpace, T &v4l2Format); - private: static ControlType v4l2CtrlType(uint32_t ctrlType); static std::unique_ptr v4l2ControlId(const v4l2_query_ext_ctrl &ctrl); diff --git a/src/libcamera/v4l2_videodevice.cpp b/src/libcamera/v4l2_videodevice.cpp index 0e3f5436..b443253d 100644 --- a/src/libcamera/v4l2_videodevice.cpp +++ b/src/libcamera/v4l2_videodevice.cpp @@ -914,6 +914,17 @@ int V4L2VideoDevice::trySetFormatMeta(V4L2DeviceFormat *format, bool set) return 0; } +namespace { + +template +std::optional getColorSpace(const T &v4l2Format) +{ + V4L2PixelFormat fourcc{ v4l2Format.pixelformat }; + return V4L2Device::toColorSpace(v4l2Format, PixelFormatInfo::info(fourcc).colourEncoding); +} + +} /* namespace */ + int V4L2VideoDevice::getFormatMultiplane(V4L2DeviceFormat *format) { struct v4l2_format v4l2Format = {}; @@ -931,8 +942,7 @@ int V4L2VideoDevice::getFormatMultiplane(V4L2DeviceFormat *format) format->size.height = pix->height; format->fourcc = V4L2PixelFormat(pix->pixelformat); format->planesCount = pix->num_planes; - format->colorSpace = - toColorSpace(*pix, PixelFormatInfo::info(format->fourcc).colourEncoding); + format->colorSpace = getColorSpace(*pix); for (unsigned int i = 0; i < format->planesCount; ++i) { format->planes[i].bpl = pix->plane_fmt[i].bytesperline; @@ -988,8 +998,7 @@ 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, PixelFormatInfo::info(format->fourcc).colourEncoding); + format->colorSpace = getColorSpace(*pix); return 0; } @@ -1013,8 +1022,7 @@ int V4L2VideoDevice::getFormatSingleplane(V4L2DeviceFormat *format) format->planesCount = 1; format->planes[0].bpl = pix->bytesperline; format->planes[0].size = pix->sizeimage; - format->colorSpace = - toColorSpace(*pix, PixelFormatInfo::info(format->fourcc).colourEncoding); + format->colorSpace = getColorSpace(*pix); return 0; } @@ -1056,8 +1064,7 @@ 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, PixelFormatInfo::info(format->fourcc).colourEncoding); + format->colorSpace = getColorSpace(*pix); return 0; } From patchwork Mon Aug 29 16:37:39 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Umang Jain X-Patchwork-Id: 17231 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 36154C3272 for ; Mon, 29 Aug 2022 16:38:13 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id E315161FCF; Mon, 29 Aug 2022 18:38:12 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1661791092; bh=BJE/sijghjgSBi4m+tWWT8qpCRnDSH7pzLiDtsHQR6Y=; 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=nnrB+HE9bIAvviV74CBelN5fWVx4IDcVl740JOKdJaZPVT8CZdlPNodrdo4Pv3hy0 wXdZC0lss4bxBOxu5c2Tsh69UlCvOZKBGER8ZzJBk5eHOXP3KGpJZAuDY9QiGdNcu8 erRI30EQEROLPOB70o55vzrUZ9EU//GffmUPcGmAoWjT4waDCuhWtl95e0xF/eDg8k feHuoLBij/gSZcpFkZ+j4lyGDczmKKr84fTnMT4L77RQ3QQZd40+O8ctW+EaFGY/Ty OUyn3KQvmoSq8tFZc3N2Bd+odAskebTrlGhr7GpUq34zs56yTQ9+utRiGUkgykMw/5 Z2zeP5Jg7B2qg== Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 2DE6E61FBA for ; Mon, 29 Aug 2022 18:38:09 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="tX0dchPF"; dkim-atps=neutral Received: from umang.jainideasonboard.com (unknown [IPv6:2401:4900:1f3f:1548:78ac:4a3:edc3:c28a]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id E55EC505; Mon, 29 Aug 2022 18:38:07 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1661791088; bh=BJE/sijghjgSBi4m+tWWT8qpCRnDSH7pzLiDtsHQR6Y=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=tX0dchPFM26CB+AtCuJZeamyipuTnMZBuAfmt2314fPWer3o8dVaVaDuMZpo6SqwX OEXNXw5Hh+bbIky3w44sPzjmmyKlNeSYdSXAF+mjh3wiwdNSj+akpY13AqX9FCvGC9 ZUYZq+kQhXUT/KJPPGnrfVTOjz+JLPE4IxOEgiU8= To: libcamera-devel@lists.libcamera.org Date: Mon, 29 Aug 2022 22:07:39 +0530 Message-Id: <20220829163742.1006102-5-umang.jain@ideasonboard.com> X-Mailer: git-send-email 2.37.2 In-Reply-To: <20220829163742.1006102-1-umang.jain@ideasonboard.com> References: <20220829163742.1006102-1-umang.jain@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v3 4/7] libcamera: colorspace: Rectify the ColorSpace::Srgb preset 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" Rectify the ColorSpace::Srgb to denote that it does not use any Y'Cbcr encoding and uses full range. The kernel on the other hand, recommends to use Rec601 as the encoding for V4L2_COLORSPACE_SRGB. It is not very explicit but it can be inferred that the kernel assumes V4L2_COLORSPACE_SRGB is a YUV-encoded one. However, when the data is in RGB, no encoding is required (and this is denoted by YcbcrEncoding::None in libcamera). Hence, to be clear on the libcamera colorspace API, rectify the ColorSpace::Srgb preset to use YcbcrEncoding::None and full range. Signed-off-by: Umang Jain Reviewed-by: Laurent Pinchart --- src/libcamera/color_space.cpp | 18 ++++++++++-------- src/libcamera/v4l2_device.cpp | 7 +++++-- 2 files changed, 15 insertions(+), 10 deletions(-) diff --git a/src/libcamera/color_space.cpp b/src/libcamera/color_space.cpp index 944d0e98..ec34620a 100644 --- a/src/libcamera/color_space.cpp +++ b/src/libcamera/color_space.cpp @@ -49,8 +49,13 @@ namespace libcamera { * - Rec.2020 * * Note that there is no guarantee of a 1:1 mapping between color space names - * and definitions in libcamera and V4L2. A notable difference is that the sYCC - * libcamera color space is called JPEG in V4L2 due to historical reasons. + * and definitions in libcamera and V4L2. Two notable differences are + * + * - The sRGB libcamera color space is defined for RGB formats only with no + * Y'CbCr encoding and a full quantization range, while the V4L2 SRGB color + * space has a Y'CbCr encoding and a limited quantization range. + * - The sYCC libcamera color space is called JPEG in V4L2 due to historical + * reasons. * * \todo Define the color space fully in the libcamera API to avoid referencing * V4L2 @@ -138,16 +143,13 @@ const ColorSpace ColorSpace::Raw = { }; /** - * \brief A constant representing the sRGB color space - * - * This is identical to the sYCC color space except that the Y'CbCr - * range is limited rather than full. + * \brief A constant representing the sRGB color space (RGB formats only) */ const ColorSpace ColorSpace::Srgb = { Primaries::Rec709, TransferFunction::Srgb, - YcbcrEncoding::Rec601, - Range::Limited + YcbcrEncoding::None, + Range::Full }; /** diff --git a/src/libcamera/v4l2_device.cpp b/src/libcamera/v4l2_device.cpp index 301620f8..1d899657 100644 --- a/src/libcamera/v4l2_device.cpp +++ b/src/libcamera/v4l2_device.cpp @@ -746,7 +746,11 @@ void V4L2Device::eventAvailable() static const std::map v4l2ToColorSpace = { { V4L2_COLORSPACE_RAW, ColorSpace::Raw }, - { V4L2_COLORSPACE_SRGB, ColorSpace::Srgb }, + { V4L2_COLORSPACE_SRGB, { + ColorSpace::Primaries::Rec709, + ColorSpace::TransferFunction::Srgb, + ColorSpace::YcbcrEncoding::Rec601, + ColorSpace::Range::Limited } }, { V4L2_COLORSPACE_JPEG, ColorSpace::Sycc }, { V4L2_COLORSPACE_SMPTE170M, ColorSpace::Smpte170m }, { V4L2_COLORSPACE_REC709, ColorSpace::Rec709 }, @@ -772,7 +776,6 @@ static const std::map v4l2ToRange = { static const std::vector> colorSpaceToV4l2 = { { ColorSpace::Raw, V4L2_COLORSPACE_RAW }, - { ColorSpace::Srgb, V4L2_COLORSPACE_SRGB }, { ColorSpace::Sycc, V4L2_COLORSPACE_JPEG }, { ColorSpace::Smpte170m, V4L2_COLORSPACE_SMPTE170M }, { ColorSpace::Rec709, V4L2_COLORSPACE_REC709 }, From patchwork Mon Aug 29 16:37:40 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Umang Jain X-Patchwork-Id: 17232 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 E535AC327D for ; Mon, 29 Aug 2022 16:38:13 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 8709C61FC3; Mon, 29 Aug 2022 18:38:13 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1661791093; bh=psmaUBKUBww47lbfze0f1NvxjgvL30karPZR5FG9adM=; 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=h6gcpvkbvrzqjtLJ1NrDjbD/1xd49WrcsHY99uyOBr4bpFycyyfSba4frkI4GB19z nbN8sbk1vIIbd5avitv5wY/Zc98MvaOWAl5XG9gJcfLiz87eECL6B0whFgm26ZkmFV T0Qyi3RHWKURtfBakDTaxAdZKPBVU6g0UvJXGERu1fQ77SAYtlTU76RgcazJe+wnv8 2scHBFBsj3OZoApVpFrfaK6pKFscQMMhyaqqlTjQhVJtPPdmLQhTrKT06jbDKgKG2y zQtTRENAWeEhXRnc0/D9C5lNVd1Kr+RNtJTNUBWWGPKvGsDZOy1opfuutL+zBgTbos gX/Q8Csztdlzw== Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 4ED7461FBA for ; Mon, 29 Aug 2022 18:38:11 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="DMLUJFJ0"; dkim-atps=neutral Received: from umang.jainideasonboard.com (unknown [IPv6:2401:4900:1f3f:1548:78ac:4a3:edc3:c28a]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 16058505; Mon, 29 Aug 2022 18:38:09 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1661791091; bh=psmaUBKUBww47lbfze0f1NvxjgvL30karPZR5FG9adM=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=DMLUJFJ0aNDr6U/B83K4NmUiy2fI9meRJEJIMNgb5Pm1tVRilEks5m3kX+3ZdCYr3 6Nw3n0l2r90dc91fAvsUwlKqLXLvgIzSsMC53X5tMV4wHiq2eG2o7tUh9ARxvIqP+Q nYY+69oHfBxWSBGSNqVGyJ7EqAeBSNgC58u9rU+U= To: libcamera-devel@lists.libcamera.org Date: Mon, 29 Aug 2022 22:07:40 +0530 Message-Id: <20220829163742.1006102-6-umang.jain@ideasonboard.com> X-Mailer: git-send-email 2.37.2 In-Reply-To: <20220829163742.1006102-1-umang.jain@ideasonboard.com> References: <20220829163742.1006102-1-umang.jain@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v3 5/7] libcamera: color_space: Move color space adjustment to ColorSpace class 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 CameraConfiguration::validateColorSpaces() function performs color space validation on a camera configuration, by validating the color space of each stream individually, and optionally ensuring that all streams share the same color space. The individual validation is very basic, limited to ensuring that raw formats use a raw color space. Color spaces are more constrained than that: - The Y'CbCr encoding and quantization range for RGB formats must be YcbcrEncoding::None and Range::Full respectively. - The Y'CbCr encoding for YUV formats must not be YcbcrEncoding::None. Instead of open-coding these constraints in the validateColorSpaces() function, create a new ColorSpace::adjust() function to centralize color space validation and adjustment, and use it in validateColorSpaces(). Signed-off-by: Umang Jain Signed-off-by: Laurent Pinchart Reviewed-by: Umang Jain --- include/libcamera/color_space.h | 4 ++ src/libcamera/camera.cpp | 43 ++++++-------- src/libcamera/color_space.cpp | 101 ++++++++++++++++++++++++++++++++ 3 files changed, 122 insertions(+), 26 deletions(-) diff --git a/include/libcamera/color_space.h b/include/libcamera/color_space.h index f493f72d..6d6c2829 100644 --- a/include/libcamera/color_space.h +++ b/include/libcamera/color_space.h @@ -12,6 +12,8 @@ namespace libcamera { +class PixelFormat; + class ColorSpace { public: @@ -61,6 +63,8 @@ public: static std::string toString(const std::optional &colorSpace); static std::optional fromString(const std::string &str); + + bool adjust(PixelFormat format); }; bool operator==(const ColorSpace &lhs, const ColorSpace &rhs); diff --git a/src/libcamera/camera.cpp b/src/libcamera/camera.cpp index a5c3aabe..9fe29ca9 100644 --- a/src/libcamera/camera.cpp +++ b/src/libcamera/camera.cpp @@ -317,17 +317,6 @@ std::size_t CameraConfiguration::size() const return config_.size(); } -namespace { - -bool isRaw(const PixelFormat &pixFmt) -{ - const PixelFormatInfo &info = PixelFormatInfo::info(pixFmt); - return info.isValid() && - info.colourEncoding == PixelFormatInfo::ColourEncodingRAW; -} - -} /* namespace */ - /** * \enum CameraConfiguration::ColorSpaceFlag * \brief Specify the behaviour of validateColorSpaces @@ -368,29 +357,31 @@ CameraConfiguration::Status CameraConfiguration::validateColorSpaces(ColorSpaceF Status status = Valid; /* - * Set all raw streams to the Raw color space, and make a note of the largest - * non-raw stream with a defined color space (if there is one). + * Set all raw streams to the Raw color space, and make a note of the + * largest non-raw stream with a defined color space (if there is one). */ - int index = -1; + std::optional colorSpace; + for (auto [i, cfg] : utils::enumerate(config_)) { - if (isRaw(cfg.pixelFormat)) { - if (cfg.colorSpace != ColorSpace::Raw) { - cfg.colorSpace = ColorSpace::Raw; - status = Adjusted; - } - } else if (cfg.colorSpace && (index == -1 || cfg.size > config_[i].size)) { - index = i; - } + if (!cfg.colorSpace) + continue; + + if (cfg.colorSpace->adjust(cfg.pixelFormat)) + status = Adjusted; + + if (cfg.colorSpace != ColorSpace::Raw && + (!colorSpace || cfg.size > config_[i].size)) + colorSpace = cfg.colorSpace; } - if (index < 0 || !(flags & ColorSpaceFlag::StreamsShareColorSpace)) + if (!colorSpace || !(flags & ColorSpaceFlag::StreamsShareColorSpace)) return status; /* Make all output color spaces the same, if requested. */ for (auto &cfg : config_) { - if (!isRaw(cfg.pixelFormat) && - cfg.colorSpace != config_[index].colorSpace) { - cfg.colorSpace = config_[index].colorSpace; + if (cfg.colorSpace != ColorSpace::Raw && + cfg.colorSpace != colorSpace) { + cfg.colorSpace = colorSpace; status = Adjusted; } } diff --git a/src/libcamera/color_space.cpp b/src/libcamera/color_space.cpp index ec34620a..7356bf7d 100644 --- a/src/libcamera/color_space.cpp +++ b/src/libcamera/color_space.cpp @@ -16,6 +16,8 @@ #include +#include "libcamera/internal/formats.h" + /** * \file color_space.h * \brief Class and enums to represent color spaces @@ -398,6 +400,105 @@ std::optional ColorSpace::fromString(const std::string &str) return colorSpace; } +/** + * \brief Adjust the color space to match a pixel format + * \param[in] format The pixel format + * + * Not all combinations of pixel formats and color spaces make sense. For + * instance, nobody uses a limited quantization range with raw Bayer formats, + * and the YcbcrEncoding::None encoding isn't valid for YUV formats. This + * function adjusts the ColorSpace to make it compatible with the given \a + * format, by applying the following rules: + * + * - The color space for RAW formats must be Raw. + * - The Y'CbCr encoding and quantization range for RGB formats must be + * YcbcrEncoding::None and Range::Full respectively. + * - The Y'CbCr encoding for YUV formats must not be YcbcrEncoding::None. The + * best encoding is in that case guessed based on the primaries and transfer + * function. + * + * \return True if the color space has been adjusted, or false if it was + * already compatible with the format and hasn't been changed + */ +bool ColorSpace::adjust(PixelFormat format) +{ + const PixelFormatInfo &info = PixelFormatInfo::info(format); + bool adjusted = false; + + switch (info.colourEncoding) { + case PixelFormatInfo::ColourEncodingRAW: + /* Raw formats must use the raw color space. */ + if (*this != ColorSpace::Raw) { + *this = ColorSpace::Raw; + adjusted = true; + } + break; + + case PixelFormatInfo::ColourEncodingRGB: + /* + * RGB formats can't have a Y'CbCr encoding, and must use full + * range quantization. + */ + if (ycbcrEncoding != YcbcrEncoding::None) { + ycbcrEncoding = YcbcrEncoding::None; + adjusted = true; + } + + if (range != Range::Full) { + range = Range::Full; + adjusted = true; + } + break; + + case PixelFormatInfo::ColourEncodingYUV: + if (ycbcrEncoding != YcbcrEncoding::None) + break; + + /* + * YUV formats must have a Y'CbCr encoding. Infer the most + * probable option from the transfer function and primaries. + */ + switch (transferFunction) { + case TransferFunction::Linear: + /* + * Linear YUV is not used in any standard color space, + * pick the widely supported and used Rec601 as default. + */ + ycbcrEncoding = YcbcrEncoding::Rec601; + break; + + case TransferFunction::Rec709: + switch (primaries) { + /* Raw should never happen. */ + case Primaries::Raw: + case Primaries::Smpte170m: + ycbcrEncoding = YcbcrEncoding::Rec601; + break; + case Primaries::Rec709: + ycbcrEncoding = YcbcrEncoding::Rec709; + break; + case Primaries::Rec2020: + ycbcrEncoding = YcbcrEncoding::Rec2020; + break; + } + break; + + case TransferFunction::Srgb: + /* + * Only the sYCC color space uses the sRGB transfer + * function, the corresponding encoding is Rec601. + */ + ycbcrEncoding = YcbcrEncoding::Rec601; + break; + } + + adjusted = true; + break; + } + + return adjusted; +} + /** * \brief Compare color spaces for equality * \return True if the two color spaces are identical, false otherwise From patchwork Mon Aug 29 16:37:41 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Umang Jain X-Patchwork-Id: 17233 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 BDB05C3272 for ; Mon, 29 Aug 2022 16:38:16 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 820FC61FC9; Mon, 29 Aug 2022 18:38:16 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1661791096; bh=WUe0whjXp/ttI/abCisnscXe/TV7eSKa/0M0PXQ8bXA=; 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=wxpyim4Rm7oi9ZbQSIhiRcxdxOX9gtWzl3Pli3RocmgoILP4B6PuMsZbZld0CcbHo bH9j/WHol5XbUkiu4zErCWLoe4CCLzOzXTHJcN3yU2YBkwL4gYWKnI15pd9GMDHgNn qrV9imG0PxrezmwehoF4tIG+EYRXNexdfPQiHOkrAbFYhTJPT2LDX/TN3FRlcpSo5A c999Pexar+sCbq7ZVoDnhD2efEIG/8c5wQtxprUSXtkdKOeaxM2ppozDsPyrthU+KF pCYBDXxWJa1H8sZoxNGf84NQAf3aNH9kZbvjIJZM90vYXD0CjeIPJy+rYrFzn9HKA8 IFNt0arjmSJ2Q== Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id F182F61FD0 for ; Mon, 29 Aug 2022 18:38:12 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="EHlKk9eW"; dkim-atps=neutral Received: from umang.jainideasonboard.com (unknown [IPv6:2401:4900:1f3f:1548:78ac:4a3:edc3:c28a]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id E3DE4505; Mon, 29 Aug 2022 18:38:11 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1661791092; bh=WUe0whjXp/ttI/abCisnscXe/TV7eSKa/0M0PXQ8bXA=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=EHlKk9eWkHntxjsmbkBgvgwUtNFF1uhTDVqV8tbf0FtQxeMpC2jwPzEwCjH1aDbTQ 1yy1hsO7zv1zIr85EV80U1lbB0OHKhmR+Eo8OFhifHxekDOOa36eD6ekIbAT2uz6Zq zkZTKRS+hr6/Sakh+weVJGl007K3Q3r4vXkiRVgc= To: libcamera-devel@lists.libcamera.org Date: Mon, 29 Aug 2022 22:07:41 +0530 Message-Id: <20220829163742.1006102-7-umang.jain@ideasonboard.com> X-Mailer: git-send-email 2.37.2 In-Reply-To: <20220829163742.1006102-1-umang.jain@ideasonboard.com> References: <20220829163742.1006102-1-umang.jain@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v3 6/7] tests: stream: Add a colorspace adjustment test 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" ColorSpace can be adjusted based on the stream's pixelFormat being requested. Add a test to check the adjustment logic defined in ColorSpace::adjust(). Signed-off-by: Umang Jain Reviewed-by: Laurent Pinchart Reviewed-by: Laurent Pinchart --- test/stream/meson.build | 1 + test/stream/stream_colorspace.cpp | 87 +++++++++++++++++++++++++++++++ 2 files changed, 88 insertions(+) create mode 100644 test/stream/stream_colorspace.cpp diff --git a/test/stream/meson.build b/test/stream/meson.build index 73608ffd..89f51c18 100644 --- a/test/stream/meson.build +++ b/test/stream/meson.build @@ -1,6 +1,7 @@ # SPDX-License-Identifier: CC0-1.0 stream_tests = [ + ['stream_colorspace', 'stream_colorspace.cpp'], ['stream_formats', 'stream_formats.cpp'], ] diff --git a/test/stream/stream_colorspace.cpp b/test/stream/stream_colorspace.cpp new file mode 100644 index 00000000..7b7e84e0 --- /dev/null +++ b/test/stream/stream_colorspace.cpp @@ -0,0 +1,87 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (C) 2022, Ideas on Board Oy. + * + * stream_colorspace.cpp - Stream colorspace tests + */ + +#include + +#include +#include +#include + +#include "test.h" + +using namespace libcamera; +using namespace std; + +class TestCameraConfiguration : public CameraConfiguration +{ +public: + TestCameraConfiguration() + : CameraConfiguration() + { + } + + Status validate() override + { + return validateColorSpaces(); + } +}; + +class StreamColorSpaceTest : public Test +{ +protected: + int run() + { + StreamConfiguration cfg; + cfg.size = { 640, 320 }; + cfg.pixelFormat = formats::YUV422; + cfg.colorSpace = ColorSpace::Srgb; + config_.addConfiguration(cfg); + + StreamConfiguration &streamCfg = config_.at(0); + + /* + * YUV pixelformat with sRGB colorspace should have Y'CbCr encoding + * adjusted. + */ + config_.validate(); + if (streamCfg.colorSpace->ycbcrEncoding == ColorSpace::YcbcrEncoding::None) + return TestFail; + + /* + * For YUV pixelFormat, encoding should picked up according to + * primaries and transfer function, if 'None' is specified. + */ + streamCfg.pixelFormat = formats::YUV422; + streamCfg.colorSpace = ColorSpace(ColorSpace::Primaries::Rec2020, + ColorSpace::TransferFunction::Rec709, + ColorSpace::YcbcrEncoding::None, + ColorSpace::Range::Limited); + config_.validate(); + if (streamCfg.colorSpace->ycbcrEncoding != ColorSpace::YcbcrEncoding::Rec2020) + return TestFail; + + /* For RGB pixelFormat, sRGB colorspace shouldn't get adjusted */ + streamCfg.pixelFormat = formats::RGB888; + streamCfg.colorSpace = ColorSpace::Srgb; + config_.validate(); + if (streamCfg.colorSpace != ColorSpace::Srgb) + return TestFail; + + /* Raw formats should always set colorspace to ColorSpace::Raw */ + streamCfg.pixelFormat = formats::SBGGR8; + streamCfg.colorSpace = ColorSpace::Rec709; + config_.validate(); + if (streamCfg.colorSpace != ColorSpace::Raw) + return TestFail; + + return TestPass; + } + + TestCameraConfiguration config_; +}; + +TEST_REGISTER(StreamColorSpaceTest) From patchwork Mon Aug 29 16:37:42 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Umang Jain X-Patchwork-Id: 17234 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 3F437C327D for ; Mon, 29 Aug 2022 16:38:17 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id ED40061FC5; Mon, 29 Aug 2022 18:38:16 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1661791097; bh=Wng1Mo/xoAj+xM0p8h+qRx6PX7Upedfdx+ODS/pg/nE=; h=To:Date:In-Reply-To:References:Subject:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc: From; b=0EDnfFHPuzUvtxxzeYtepIYEPYujeUqDz+ZkIcNVEI24TTSFr7WU3w8cklbKMFImo gUi4hCjaELeumlzK38F//BZHZnOeWEW9MpF7bySEJiXgUzOLI+GSBxou2wmImPPoka 3q33B0T4iZUInaLCJFsNPssdMuKP1PL98zmpDNK1TMxhnAtb1zPHP0LdyjACvW5kND ZBTavdjxwpjVdXGsW6FwlXU2Q80sabyrwZ67uaRN2mA6S57nspPK/b9LA1AjTpoSoF lududZ0llc6JB3Ngm+kG+wrkH7B9xoOjT2MLcuOZNpD2hqUjp8yZduVhbnzfCCN83r 0kGFTfiHaMSxA== Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 7E6EC61FBA for ; Mon, 29 Aug 2022 18:38:15 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="FsXXiUkb"; dkim-atps=neutral Received: from umang.jainideasonboard.com (unknown [IPv6:2401:4900:1f3f:1548:78ac:4a3:edc3:c28a]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id D6780A1D; Mon, 29 Aug 2022 18:38:13 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1661791095; bh=Wng1Mo/xoAj+xM0p8h+qRx6PX7Upedfdx+ODS/pg/nE=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=FsXXiUkbXWJuHRXB77B/K8BgkUs9XvXLxLZG81A24jOyZWWFOcDb162fpO4Qne9Wh v9Rq4pvnIpA6XNdVwm+7YQ2Z1vPYdmZS10zX5fxI6mTVZGiDJfMH61aERet57j3UxC 5lLd02z3EI5HA/gdYyuRYqRJAWBKtd8oxFD68BPg= To: libcamera-devel@lists.libcamera.org Date: Mon, 29 Aug 2022 22:07:42 +0530 Message-Id: <20220829163742.1006102-8-umang.jain@ideasonboard.com> X-Mailer: git-send-email 2.37.2 In-Reply-To: <20220829163742.1006102-1-umang.jain@ideasonboard.com> References: <20220829163742.1006102-1-umang.jain@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v3 7/7] gstreamer: Provide colorimetry <> ColorSpace mappings 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 Cc: Rishikesh Donadkar Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" From: Rishikesh Donadkar Provide colorimetry <=> libcamera::ColorSpace mappings via: - GstVideoColorimetry colorimetry_from_colorspace(colorspace); - ColorSpace colorspace_from_colorimetry(colorimetry); Read the colorimetry field from caps into the stream configuration. After stream validation, the sensor supported colorimetry will be retrieved and the caps will be updated accordingly. Colorimetry support for gstlibcamera currently undertakes only one argument. Multiple colorimetry support shall be introduced in subsequent commits. Signed-off-by: Rishikesh Donadkar Signed-off-by: Umang Jain Reviewed-by: Laurent Pinchart --- src/gstreamer/gstlibcamera-utils.cpp | 169 +++++++++++++++++++++++++++ 1 file changed, 169 insertions(+) diff --git a/src/gstreamer/gstlibcamera-utils.cpp b/src/gstreamer/gstlibcamera-utils.cpp index 5a21a391..c7b44a8e 100644 --- a/src/gstreamer/gstlibcamera-utils.cpp +++ b/src/gstreamer/gstlibcamera-utils.cpp @@ -57,6 +57,152 @@ static struct { /* \todo NV42 is used in libcamera but is not mapped in GStreamer yet. */ }; +static GstVideoColorimetry +colorimetry_from_colorspace(const ColorSpace &colorSpace) +{ + GstVideoColorimetry colorimetry; + + switch (colorSpace.primaries) { + case ColorSpace::Primaries::Raw: + colorimetry.primaries = GST_VIDEO_COLOR_PRIMARIES_UNKNOWN; + break; + case ColorSpace::Primaries::Smpte170m: + colorimetry.primaries = GST_VIDEO_COLOR_PRIMARIES_SMPTE170M; + break; + case ColorSpace::Primaries::Rec709: + colorimetry.primaries = GST_VIDEO_COLOR_PRIMARIES_BT709; + break; + case ColorSpace::Primaries::Rec2020: + colorimetry.primaries = GST_VIDEO_COLOR_PRIMARIES_BT2020; + break; + } + + switch (colorSpace.transferFunction) { + case ColorSpace::TransferFunction::Linear: + colorimetry.transfer = GST_VIDEO_TRANSFER_GAMMA10; + break; + case ColorSpace::TransferFunction::Srgb: + colorimetry.transfer = GST_VIDEO_TRANSFER_SRGB; + break; + case ColorSpace::TransferFunction::Rec709: + colorimetry.transfer = GST_VIDEO_TRANSFER_BT709; + break; + } + + switch (colorSpace.ycbcrEncoding) { + case ColorSpace::YcbcrEncoding::None: + colorimetry.matrix = GST_VIDEO_COLOR_MATRIX_RGB; + break; + case ColorSpace::YcbcrEncoding::Rec601: + colorimetry.matrix = GST_VIDEO_COLOR_MATRIX_BT601; + break; + case ColorSpace::YcbcrEncoding::Rec709: + colorimetry.matrix = GST_VIDEO_COLOR_MATRIX_BT709; + break; + case ColorSpace::YcbcrEncoding::Rec2020: + colorimetry.matrix = GST_VIDEO_COLOR_MATRIX_BT2020; + break; + } + + switch (colorSpace.range) { + case ColorSpace::Range::Full: + colorimetry.range = GST_VIDEO_COLOR_RANGE_0_255; + break; + case ColorSpace::Range::Limited: + colorimetry.range = GST_VIDEO_COLOR_RANGE_16_235; + break; + } + + return colorimetry; +} + +static std::optional +colorspace_from_colorimetry(const GstVideoColorimetry &colorimetry) +{ + std::optional colorspace; + + switch (colorimetry.primaries) { + case GST_VIDEO_COLOR_PRIMARIES_UNKNOWN: + /* Unknown primaries map to raw colorspace in gstreamer */ + return ColorSpace::Raw; + case GST_VIDEO_COLOR_PRIMARIES_SMPTE170M: + colorspace->primaries = ColorSpace::Primaries::Smpte170m; + break; + case GST_VIDEO_COLOR_PRIMARIES_BT709: + colorspace->primaries = ColorSpace::Primaries::Rec709; + break; + case GST_VIDEO_COLOR_PRIMARIES_BT2020: + colorspace->primaries = ColorSpace::Primaries::Rec2020; + break; + default: + GST_WARNING("Colorimetry primaries %d not mapped in gstlibcamera", + colorimetry.primaries); + return std::nullopt; + } + + switch (colorimetry.transfer) { + /* Transfer function mappings inspired from v4l2src plugin */ + case GST_VIDEO_TRANSFER_GAMMA18: + case GST_VIDEO_TRANSFER_GAMMA20: + case GST_VIDEO_TRANSFER_GAMMA22: + case GST_VIDEO_TRANSFER_GAMMA28: + GST_WARNING("GAMMA 18, 20, 22, 28 transfer functions not supported"); + /* fallthrough */ + case GST_VIDEO_TRANSFER_GAMMA10: + colorspace->transferFunction = ColorSpace::TransferFunction::Linear; + break; + case GST_VIDEO_TRANSFER_SRGB: + colorspace->transferFunction = ColorSpace::TransferFunction::Srgb; + break; + case GST_VIDEO_TRANSFER_BT601: + case GST_VIDEO_TRANSFER_BT2020_12: + case GST_VIDEO_TRANSFER_BT2020_10: + case GST_VIDEO_TRANSFER_BT709: + colorspace->transferFunction = ColorSpace::TransferFunction::Rec709; + break; + default: + GST_WARNING("Colorimetry transfer function %d not mapped in gstlibcamera", + colorimetry.transfer); + return std::nullopt; + } + + switch (colorimetry.matrix) { + case GST_VIDEO_COLOR_MATRIX_RGB: + colorspace->ycbcrEncoding = ColorSpace::YcbcrEncoding::None; + break; + /* FCC is about the same as BT601 with less digit */ + case GST_VIDEO_COLOR_MATRIX_FCC: + case GST_VIDEO_COLOR_MATRIX_BT601: + colorspace->ycbcrEncoding = ColorSpace::YcbcrEncoding::Rec601; + break; + case GST_VIDEO_COLOR_MATRIX_BT709: + colorspace->ycbcrEncoding = ColorSpace::YcbcrEncoding::Rec709; + break; + case GST_VIDEO_COLOR_MATRIX_BT2020: + colorspace->ycbcrEncoding = ColorSpace::YcbcrEncoding::Rec2020; + break; + default: + GST_WARNING("Colorimetry matrix %d not mapped in gstlibcamera", + colorimetry.matrix); + return std::nullopt; + } + + switch (colorimetry.range) { + case GST_VIDEO_COLOR_RANGE_0_255: + colorspace->range = ColorSpace::Range::Full; + break; + case GST_VIDEO_COLOR_RANGE_16_235: + colorspace->range = ColorSpace::Range::Limited; + break; + default: + GST_WARNING("Colorimetry range %d not mapped in gstlibcamera", + colorimetry.range); + return std::nullopt; + } + + return colorspace; +} + static GstVideoFormat pixel_format_to_gst_format(const PixelFormat &format) { @@ -151,6 +297,18 @@ gst_libcamera_stream_configuration_to_caps(const StreamConfiguration &stream_cfg "width", G_TYPE_INT, stream_cfg.size.width, "height", G_TYPE_INT, stream_cfg.size.height, nullptr); + + if (stream_cfg.colorSpace) { + GstVideoColorimetry colorimetry = colorimetry_from_colorspace(stream_cfg.colorSpace.value()); + gchar *colorimetry_str = gst_video_colorimetry_to_string(&colorimetry); + + if (colorimetry_str) + gst_structure_set(s, "colorimetry", G_TYPE_STRING, colorimetry_str, nullptr); + else + g_error("Got invalid colorimetry from ColorSpace: %s", + ColorSpace::toString(stream_cfg.colorSpace).c_str()); + } + gst_caps_append_structure(caps, s); return caps; @@ -234,6 +392,17 @@ gst_libcamera_configure_stream_from_caps(StreamConfiguration &stream_cfg, gst_structure_get_int(s, "height", &height); stream_cfg.size.width = width; stream_cfg.size.height = height; + + /* Configure colorimetry */ + if (gst_structure_has_field(s, "colorimetry")) { + const gchar *colorimetry_str = gst_structure_get_string(s, "colorimetry"); + GstVideoColorimetry colorimetry; + + if (!gst_video_colorimetry_from_string(&colorimetry, colorimetry_str)) + g_critical("Invalid colorimetry %s", colorimetry_str); + + stream_cfg.colorSpace = colorspace_from_colorimetry(colorimetry); + } } #if !GST_CHECK_VERSION(1, 17, 1)