From patchwork Wed Jan 21 09:07:03 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Umang Jain X-Patchwork-Id: 25900 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 61804BDCBF for ; Wed, 21 Jan 2026 09:06:29 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id D526061FCB; Wed, 21 Jan 2026 10:06:26 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=igalia.com header.i=@igalia.com header.b="XFXb3iJH"; dkim-atps=neutral Received: from fanzine2.igalia.com (fanzine2.igalia.com [213.97.179.56]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id AA8C261FBF for ; Wed, 21 Jan 2026 10:06:22 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=igalia.com; s=20170329; h=Content-Transfer-Encoding:MIME-Version:References:In-Reply-To: Message-ID:Date:Subject:Cc:To:From:Sender:Reply-To:Content-Type:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Id:List-Help:List-Unsubscribe:List-Subscribe: List-Post:List-Owner:List-Archive; bh=Yncsx+sYeywIY/Nc9NHpNEGOVrm0gKrJgWc9wPDsXmQ=; b=XFXb3iJHCruWLkCYZ/QXy68FWh y1mopKyyipVwKZN7AhLF4eFfKBIQJq60c3voosKNrjO8VlsA9aoKv0ijsV8BnY3+dP8YJEJbFo5kR swYzF47miP44SLxhQUfHg6EQEuq+XGHKtDkAhx3oqK7sxm1TyVeJUiLAauOUpnErAQrZAyIQYaCu8 dHo9H/+OHDc6McSYQDvPltjRpU1pin1b41HvWKbVm8/8dqTfG7PCMEAlt9K1pT7mEA9cbS0MXnidB 76/c2xKwh8y1hYZTiJVcp0naCGrR977KAhjky3SSAemFaxGWF6cdWpuHvw0yQdBjq/veOnrQQxoTc CIeehX9Q==; Received: from [49.36.125.126] (helo=uajain) by fanzine2.igalia.com with esmtpsa (Cipher TLS1.3:ECDHE_X25519__RSA_PSS_RSAE_SHA256__AES_256_GCM:256) (Exim) id 1viUAP-007xDQ-JL; Wed, 21 Jan 2026 10:06:22 +0100 From: Umang Jain To: libcamera-devel@lists.libcamera.org Cc: Umang Jain Subject: [PATCH 1/3] pipeline: virtual: image_frame_generator: Explicitly include libcamera headers Date: Wed, 21 Jan 2026 14:37:03 +0530 Message-ID: <20260121090705.274081-2-uajain@igalia.com> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20260121090705.274081-1-uajain@igalia.com> References: <20260121090705.274081-1-uajain@igalia.com> MIME-Version: 1.0 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: , Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" Directly include libcamera headers instead of including them indirectly via frame_generator.h. Signed-off-by: Umang Jain Reviewed-by: Barnabás Pőcze --- src/libcamera/pipeline/virtual/image_frame_generator.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/libcamera/pipeline/virtual/image_frame_generator.h b/src/libcamera/pipeline/virtual/image_frame_generator.h index 42a077ba..851ddbc0 100644 --- a/src/libcamera/pipeline/virtual/image_frame_generator.h +++ b/src/libcamera/pipeline/virtual/image_frame_generator.h @@ -13,6 +13,9 @@ #include #include +#include +#include + #include "frame_generator.h" namespace libcamera { From patchwork Wed Jan 21 09:07:04 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Umang Jain X-Patchwork-Id: 25901 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 BF8AFC327D for ; Wed, 21 Jan 2026 09:06:30 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 9B65D61FC6; Wed, 21 Jan 2026 10:06:27 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=igalia.com header.i=@igalia.com header.b="nkLVG18G"; dkim-atps=neutral Received: from fanzine2.igalia.com (fanzine2.igalia.com [213.97.179.56]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 40AC0615B2 for ; Wed, 21 Jan 2026 10:06:24 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=igalia.com; s=20170329; h=Content-Transfer-Encoding:MIME-Version:References:In-Reply-To: Message-ID:Date:Subject:Cc:To:From:Sender:Reply-To:Content-Type:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Id:List-Help:List-Unsubscribe:List-Subscribe: List-Post:List-Owner:List-Archive; bh=AZizNohLGekzI24KUjaMEqFoDsP5O0Oy1eEvqR5Cwis=; b=nkLVG18GUj9MycFU7fCpPwQpr2 O46vuiSEWW41DmsIdANI8/ip/K1C51rDLQ3SLhDDmMkpMLUisieEZobxh2yj3pVKzddjij9Lg7NWo e3LENCCGGJ1dFiqTCLLT99VihrvCWQ65pn7WZRbAFhq0j0lEfO4iv+1GMeqKjbWn0ff97+SVicr3J tHPX+qnETCSq0H2m8neQ6dm5xop1ijHR8EpfmipkSLgauM63dzr8j7mnCCZNR4fVv3/gMsAvMaqFI fzdZZK/FD+76L0vOofg8HjjXidKpu+VY8EsV3ZfFy+EGDWCxnEDDPUrg7yJfYHomjlN2PXsQ/XGkc Z8j1poDQ==; Received: from [49.36.125.126] (helo=uajain) by fanzine2.igalia.com with esmtpsa (Cipher TLS1.3:ECDHE_X25519__RSA_PSS_RSAE_SHA256__AES_256_GCM:256) (Exim) id 1viUAR-007xDQ-9u; Wed, 21 Jan 2026 10:06:23 +0100 From: Umang Jain To: libcamera-devel@lists.libcamera.org Cc: Umang Jain Subject: [PATCH 2/3] pipeline: virtual: Implement colorspace() getter for frame generators Date: Wed, 21 Jan 2026 14:37:04 +0530 Message-ID: <20260121090705.274081-3-uajain@igalia.com> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20260121090705.274081-1-uajain@igalia.com> References: <20260121090705.274081-1-uajain@igalia.com> MIME-Version: 1.0 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: , Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" Each frame generator can decide what colorspace is deemed fit for their generated frames. Provide a virtual getter colorspace() and implement it the TestPatternGenerator and ImageFrameGenerator classes. Signed-off-by: Umang Jain --- .../pipeline/virtual/frame_generator.h | 3 +++ .../pipeline/virtual/image_frame_generator.cpp | 9 +++++++++ .../pipeline/virtual/image_frame_generator.h | 2 ++ .../virtual/test_pattern_generator.cpp | 18 ++++++++++++++++++ .../pipeline/virtual/test_pattern_generator.h | 4 ++++ 5 files changed, 36 insertions(+) diff --git a/src/libcamera/pipeline/virtual/frame_generator.h b/src/libcamera/pipeline/virtual/frame_generator.h index a0658c45..acbf2cc1 100644 --- a/src/libcamera/pipeline/virtual/frame_generator.h +++ b/src/libcamera/pipeline/virtual/frame_generator.h @@ -7,6 +7,7 @@ #pragma once +#include #include #include @@ -19,6 +20,8 @@ public: virtual void configure(const Size &size) = 0; + virtual const ColorSpace colorspace() = 0; + virtual int generateFrame(const Size &size, const FrameBuffer *buffer) = 0; diff --git a/src/libcamera/pipeline/virtual/image_frame_generator.cpp b/src/libcamera/pipeline/virtual/image_frame_generator.cpp index d1545b5d..bab3cfdc 100644 --- a/src/libcamera/pipeline/virtual/image_frame_generator.cpp +++ b/src/libcamera/pipeline/virtual/image_frame_generator.cpp @@ -149,6 +149,15 @@ int ImageFrameGenerator::generateFrame(const Size &size, const FrameBuffer *buff return 0; } +const ColorSpace ImageFrameGenerator::colorspace() +{ + /* + * libyuv ensures sYCC colorspace of frames during MJPGToNV12() + * conversion. + */ + return ColorSpace::Sycc; +} + /* * \var ImageFrameGenerator::imageFrameDatas_ * \brief List of pointers to the not scaled image buffers diff --git a/src/libcamera/pipeline/virtual/image_frame_generator.h b/src/libcamera/pipeline/virtual/image_frame_generator.h index 851ddbc0..24c362e6 100644 --- a/src/libcamera/pipeline/virtual/image_frame_generator.h +++ b/src/libcamera/pipeline/virtual/image_frame_generator.h @@ -13,6 +13,7 @@ #include #include +#include #include #include @@ -41,6 +42,7 @@ private: void configure(const Size &size) override; int generateFrame(const Size &size, const FrameBuffer *buffer) override; + const ColorSpace colorspace() override; std::vector imageFrameDatas_; std::vector scaledFrameDatas_; diff --git a/src/libcamera/pipeline/virtual/test_pattern_generator.cpp b/src/libcamera/pipeline/virtual/test_pattern_generator.cpp index 745be83b..04efe6cc 100644 --- a/src/libcamera/pipeline/virtual/test_pattern_generator.cpp +++ b/src/libcamera/pipeline/virtual/test_pattern_generator.cpp @@ -62,6 +62,24 @@ int TestPatternGenerator::generateFrame(const Size &size, return ret; } +/* + * libyuv internally converts ARGB<>YUV following the BT.601 colorspace. + * The corresponding YCbCr encoding is ColorSpace::YcbcrEncoding::Rec601 + * with limited range. + * + * Since the test patterns generation occurs in RGB, transfer function is set + * to ColorSpace::TransferFunction::Srgb. Color primaries is assumed + * ColorSpace::Primaries::Rec709 for the RGB test patterns. + */ +const ColorSpace TestPatternGenerator::colorspace() +{ + ColorSpace colorspace{ ColorSpace::Primaries::Rec709, + ColorSpace::TransferFunction::Srgb, + ColorSpace::YcbcrEncoding::Rec601, + ColorSpace::Range::Limited }; + return colorspace; +} + void ColorBarsGenerator::configure(const Size &size) { constexpr uint8_t kColorBar[8][3] = { diff --git a/src/libcamera/pipeline/virtual/test_pattern_generator.h b/src/libcamera/pipeline/virtual/test_pattern_generator.h index 2a51bd31..fb2de65f 100644 --- a/src/libcamera/pipeline/virtual/test_pattern_generator.h +++ b/src/libcamera/pipeline/virtual/test_pattern_generator.h @@ -9,6 +9,7 @@ #include +#include #include #include @@ -29,6 +30,9 @@ public: protected: /* Buffer of test pattern template */ std::unique_ptr template_; + +private: + const ColorSpace colorspace() override; }; class ColorBarsGenerator : public TestPatternGenerator From patchwork Wed Jan 21 09:07:05 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Umang Jain X-Patchwork-Id: 25902 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 88F1EBDCBF for ; Wed, 21 Jan 2026 09:06:31 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 4887C61FD3; Wed, 21 Jan 2026 10:06:30 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=igalia.com header.i=@igalia.com header.b="QKOm0lZI"; dkim-atps=neutral Received: from fanzine2.igalia.com (fanzine2.igalia.com [213.97.179.56]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 0BB2B61FCF for ; Wed, 21 Jan 2026 10:06:26 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=igalia.com; s=20170329; h=Content-Transfer-Encoding:MIME-Version:References:In-Reply-To: Message-ID:Date:Subject:Cc:To:From:Sender:Reply-To:Content-Type:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Id:List-Help:List-Unsubscribe:List-Subscribe: List-Post:List-Owner:List-Archive; bh=rqYmOETbgScdIWiBErDSx0hw8farFh8j8WEQ0XQEQLc=; b=QKOm0lZI5diqCRbxAdO62oWTMr FPrzR6eeOaBD572VQpL3Ewts4THU6mo7GjNTz1nb5wcCGAsbGxatHtkMAkjf6ShyItjEmJNxIG2xx VApreIMvXauRvMz5PTGH1UW/jWIZTr46/PBm2oH8vvfATTzS9SFjd9ZWtWBI10XdQJcMEbxTHp0+A kr7BfCrfm/okkR8AGeac/Eng8wJWOQJpuwZbKbHjsRtEqH1b+2eqtRW/v66PpFeEmqq19EjVai3+G 78a0EvtB2Y0gu1TwxJEu8r2gbPAmJjCM/bdv/ZiY9srepAyjFVbxpMkpeMZ9HYfmrRV2MAFkXrVtv TDSHl1NQ==; Received: from [49.36.125.126] (helo=uajain) by fanzine2.igalia.com with esmtpsa (Cipher TLS1.3:ECDHE_X25519__RSA_PSS_RSAE_SHA256__AES_256_GCM:256) (Exim) id 1viUAT-007xDQ-0A; Wed, 21 Jan 2026 10:06:25 +0100 From: Umang Jain To: libcamera-devel@lists.libcamera.org Cc: Umang Jain Subject: [PATCH 3/3] pipeline: virtual: Rectify validation of colorspace Date: Wed, 21 Jan 2026 14:37:05 +0530 Message-ID: <20260121090705.274081-4-uajain@igalia.com> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20260121090705.274081-1-uajain@igalia.com> References: <20260121090705.274081-1-uajain@igalia.com> MIME-Version: 1.0 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: , Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" Now that each frame generator class supports the colorspace information using the colorspace() getter, use that to validate (or set) the colorspace of a particular stream configuration instead of a incorrect hard-coded one. Fixes: 5d2d005306ad ("pipeline: virtual: Provide and validate colorspace") Signed-off-by: Umang Jain Reviewed-by: Barnabás Pőcze --- src/libcamera/pipeline/virtual/virtual.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/libcamera/pipeline/virtual/virtual.cpp b/src/libcamera/pipeline/virtual/virtual.cpp index 40c35264..3d205a6c 100644 --- a/src/libcamera/pipeline/virtual/virtual.cpp +++ b/src/libcamera/pipeline/virtual/virtual.cpp @@ -185,7 +185,7 @@ CameraConfiguration::Status VirtualCameraConfiguration::validate() status = Adjusted; } - for (StreamConfiguration &cfg : config_) { + for (auto [i, cfg] : utils::enumerate(config_)) { bool adjusted = false; bool found = false; for (const auto &resolution : data_->config_.resolutions) { @@ -214,8 +214,9 @@ CameraConfiguration::Status VirtualCameraConfiguration::validate() adjusted = true; } - if (cfg.colorSpace != ColorSpace::Rec709) { - cfg.colorSpace = ColorSpace::Rec709; + const ColorSpace colorspace = data_->streamConfigs_[i].frameGenerator->colorspace(); + if (cfg.colorSpace != colorspace) { + cfg.colorSpace = colorspace; status = Adjusted; adjusted = true; } @@ -289,7 +290,6 @@ PipelineHandlerVirtual::generateConfiguration(Camera *camera, cfg.pixelFormat = pixelFormat; cfg.size = data->config_.maxResolutionSize; cfg.bufferCount = VirtualCameraConfiguration::kBufferCount; - cfg.colorSpace = ColorSpace::Rec709; config->addConfiguration(cfg); }