From patchwork Fri Dec 16 14:33:43 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Plowman X-Patchwork-Id: 18036 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 E0F8FC3200 for ; Fri, 16 Dec 2022 14:33:52 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 8FE06633A5; Fri, 16 Dec 2022 15:33:52 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1671201232; bh=QhaPnfHsQyN18DFbE/ITvSBem1Qe71uKP2mAuiFWaBU=; 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=HXe+g2EhEBhnHg4ohsDbp9UiHF8V0ReMB9y2xuOcMy5xqVgLtvnR4a7scyCHAUud4 6jI7y0fBwcl/yG503VFUTswfdUlf/jsn13e5n+qV0LoEJHas4THz3IDVAikgZD8m/Q GTw5Wc1jj2oehVHVpnVaZVsvkTB8eb+vHJ6IOrTko7RkMkzOV1dcq3etiEs/AoQh6j KgF48Cs3egST16HLkSjGUJMsoXIKEgIehvbTSTmrd97esPGmxXI0OfofunaF1uQG5V 3OSBix5pDy30o73xqaT5ktF1MYCB6+EilN3CAW9sdbZvj04iA1SLLMLZaAFJ3eHgqq nAFCnM66kG0wg== Received: from mail-ej1-x632.google.com (mail-ej1-x632.google.com [IPv6:2a00:1450:4864:20::632]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 529146339A for ; Fri, 16 Dec 2022 15:33:49 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (2048-bit key; unprotected) header.d=raspberrypi.com header.i=@raspberrypi.com header.b="QBhq41tw"; dkim-atps=neutral Received: by mail-ej1-x632.google.com with SMTP id t17so6643456eju.1 for ; Fri, 16 Dec 2022 06:33:49 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=raspberrypi.com; s=google; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=Wm7vFBxaO4oAVnSNjseltZOQRGnDDL5NMbu478QBPD8=; b=QBhq41twK/6MFRYMUOnquBBy+QRC24XZKMqj0iYGikD/1La7zjoeAOVfhE7Hfm7K+8 TFX8Zl0IKOOSrsghDYI2/jUDbKmDQjd85Vssiim+OgACu/oCaVjD/9JMyu4ZzhgV2+iu 1Lx3wW6depF6cP3gwdgpKh7hVhvt6k2HA+ryjuoDwisTM5YWHi6XsdZbVTdwzs67I1CM R2EpQwPa+9Xu58hoyeN3FwXcbiUKrxT2VIC088LmK/hPH0Cjo83qdOVhI1sj1zTELnAH 2/JkgRk37Xf+pEadIAuhok1RPxG/VoNcZDBnMtuCVKCj0pi5ez1abIUDhkybZCYTW/8o Q4vA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=Wm7vFBxaO4oAVnSNjseltZOQRGnDDL5NMbu478QBPD8=; b=iBYakKgbw2erEQTDZqjXPueN4RLgCKP1DOEZRncSzKb+gzcN0z+ZkBic4uwbm79IJY 2U4zJYzFrU98/wlw01+zDwXh/67lbo6VOE3QSTn9zaGII3FiGbBsCeiPWe9UUmbR1s9r 5GY+JOc/XNSGcFEPBhhGyfSenzZylPNk3ZzJMQxQBWajHhd56x27E3y5KNk+Fcvru5Yz ZeQ5sZepmgVQrjDsfVikemDIDwf3SMB303MZQ27/w6/sDNH0Uv7RRmsbWBQdizRBeTyY +B33cDdb1qaeVX9wmVGxNef0x1nAk3VR1D3Npe4KVOiQByeYebCWP9wkfSizmFD5GI7V R+pw== X-Gm-Message-State: ANoB5pkrKlQniNch2Lwf50/Sj/x8F3T4Y/uAJIKjJGrn0RlB1e65C7Fg QIhSNfp2g9XZB6T/rOZnQSIFKoZbSk5s1eRB X-Google-Smtp-Source: AA0mqf5W6TXdB9uezE/rb1smyDsDP8DBUsuMX6v+PwKHvzI9q7CAuft4KknnHEOR88HTEFJJUwXueg== X-Received: by 2002:a17:906:a852:b0:7c0:e0d8:9500 with SMTP id dx18-20020a170906a85200b007c0e0d89500mr26884793ejb.75.1671201228669; Fri, 16 Dec 2022 06:33:48 -0800 (PST) Received: from pi4-davidp.lan (plowpeople3.plus.com. [80.229.223.72]) by smtp.gmail.com with ESMTPSA id mb4-20020a170906eb0400b0073dd8e5a39fsm907903ejb.156.2022.12.16.06.33.48 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 16 Dec 2022 06:33:48 -0800 (PST) To: libcamera-devel@lists.libcamera.org Date: Fri, 16 Dec 2022 14:33:43 +0000 Message-Id: <20221216143344.8177-3-david.plowman@raspberrypi.com> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20221216143344.8177-1-david.plowman@raspberrypi.com> References: <20221216143344.8177-1-david.plowman@raspberrypi.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 2/3] libcamera: camera: Fix validateColorSpaces not to loose YCbCr encodings 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: David Plowman via libcamera-devel From: David Plowman Reply-To: David Plowman Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" When sharing the same colour spaces across streams, the "main" stream might be an RGB stream so we must stop its YCbCr information (encoding and range) from overwriting other YUV streams. Instead we also make a note of the largest stream with YCbCr information. We take the primaries and transfer function from the original "main" stream, but the YCbCr encoding and range from this second stream. Signed-off-by: David Plowman --- src/libcamera/camera.cpp | 47 +++++++++++++++++++++++++++++++++++----- 1 file changed, 42 insertions(+), 5 deletions(-) diff --git a/src/libcamera/camera.cpp b/src/libcamera/camera.cpp index 0da167a7..e0a5d03d 100644 --- a/src/libcamera/camera.cpp +++ b/src/libcamera/camera.cpp @@ -358,10 +358,13 @@ CameraConfiguration::Status CameraConfiguration::validateColorSpaces(ColorSpaceF /* * 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). + * largest non-raw stream with a defined color space (if there is one), and + * also the largest stream with YCbCr encoding information. */ std::optional colorSpace; + std::optional ycbcrColorSpace; Size size; + Size ycbcrSize; for (auto [i, cfg] : utils::enumerate(config_)) { if (!cfg.colorSpace) @@ -370,22 +373,56 @@ CameraConfiguration::Status CameraConfiguration::validateColorSpaces(ColorSpaceF if (cfg.colorSpace->adjust(cfg.pixelFormat)) status = Adjusted; - if (cfg.colorSpace != ColorSpace::Raw && cfg.size > size) { + if (cfg.colorSpace == ColorSpace::Raw) + continue; + + if (cfg.size > size) { colorSpace = cfg.colorSpace; size = cfg.size; } + + if (cfg.colorSpace->ycbcrEncoding != ColorSpace::YcbcrEncoding::None && + cfg.size > ycbcrSize) { + ycbcrColorSpace = cfg.colorSpace; + ycbcrSize = cfg.size; + } } if (!colorSpace || !(flags & ColorSpaceFlag::StreamsShareColorSpace)) return status; - /* Make all output color spaces the same, if requested. */ + /* + * Make all output color spaces the same, if requested. Note that when sharing like + * this, we copy the primaries and transfer function from the principal stream + * (the variable "colorSpace") but we mustn't use its ycbcrEncoding or range because + * it may be an RGB stream. So we take these fields instead from the "ycbcrColorSpace". + */ for (auto &cfg : config_) { - if (cfg.colorSpace != ColorSpace::Raw && - cfg.colorSpace != colorSpace) { + if (!cfg.colorSpace) { cfg.colorSpace = colorSpace; status = Adjusted; } + + if (cfg.colorSpace == ColorSpace::Raw) + continue; + + /* Ensure the primaries and transferFunction match the "main" stream. */ + if (cfg.colorSpace->primaries != colorSpace->primaries || + cfg.colorSpace->transferFunction != colorSpace->transferFunction) { + cfg.colorSpace->primaries = colorSpace->primaries; + cfg.colorSpace->transferFunction = colorSpace->transferFunction; + status = Adjusted; + } + + if (cfg.colorSpace->ycbcrEncoding != ColorSpace::YcbcrEncoding::None) { + /* Set these from the ycbcrColorSpace (which we note must exist). */ + if (ycbcrColorSpace->ycbcrEncoding != cfg.colorSpace->ycbcrEncoding || + ycbcrColorSpace->range != cfg.colorSpace->range) { + cfg.colorSpace->ycbcrEncoding = ycbcrColorSpace->ycbcrEncoding; + cfg.colorSpace->range = ycbcrColorSpace->range; + status = Adjusted; + } + } } return status;