From patchwork Fri Dec 16 14:33:44 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Plowman X-Patchwork-Id: 18037 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 7E57BC3200 for ; Fri, 16 Dec 2022 14:33:54 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 39A656339A; Fri, 16 Dec 2022 15:33:54 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1671201234; bh=eV5HFJXm9Z1pBsbWQBHCKYlzvJ3p+++ZrVJAkvfDmMM=; 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=bwDHj70P89Zm21XseWXsIkxsCOF8M0cpsI5CaZ6I1Jgpsdun4bYF2u8QmFPPYZLjN lP19lyuFcSYCQA/J9NzYuKqZfVyN08WLgQ5/d+7VcuLoO99UKKCyKTmq35694jh5dR ljrd2/XZrely19FL66yw++fc5ogZBlwPk4Yd8scA9lQ2Hj1kXh7xdvcxePlDvnYUqS x55Qk5VFj2EqP/A0Atxd8w7tEx4Xu7lITZM8IMwtrRdqRFtUv8eu5R9lx4OL35o1Pl 9qKUBDIC4S3R++Aw4Oxd2g2TvBlmy8g3hY7LC+aTZTPlQ1TZh27ogOkfouU4u9QPat baHje6mwFLZtw== Received: from mail-ej1-x62f.google.com (mail-ej1-x62f.google.com [IPv6:2a00:1450:4864:20::62f]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 1BFE96339E for ; Fri, 16 Dec 2022 15:33:50 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (2048-bit key; unprotected) header.d=raspberrypi.com header.i=@raspberrypi.com header.b="pY90ILlO"; dkim-atps=neutral Received: by mail-ej1-x62f.google.com with SMTP id ud5so6616293ejc.4 for ; Fri, 16 Dec 2022 06:33:50 -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=r9aZV0AFWGsOMolbu6TRUsUyPIXMvru1Qfz14ROxvqE=; b=pY90ILlOIsGu9SXLESXbX2ysfwfTV3+WAlVwAMUlyPzhEz8QGlU8yIpvbTVyvhKSSj vIWMspRtVxCfc+st1UZCkwbFWmZXqXfPnprOLdE6fBvQdO0FLfRpzR6UfeDw5Mr5+Hw/ brqJeNRS3qCYpeAB8CYngCE9ZGZsd3x6fGJwo2RirjGCCu60DYLiKSrEaMVL4ui02DG6 +P4CWuCwT5cZHSC4IcY/SxidNqKB7NqLfd1MtUba/XvNrjgYZ4rFTkVvxKARw4kbHKce 06I602GwXqDpsU7p0LW3r3tuLDBYqsUU5eRkY7+Yded3IGYzDwJPm3f66uK+sb3CFwdO w0BA== 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=r9aZV0AFWGsOMolbu6TRUsUyPIXMvru1Qfz14ROxvqE=; b=DHUDVJCah1O1K4JvbjqftvEg9/FWTwBLqD7sxVOEdStpgMufAM41zheTpkABRk+vlC DMrGucyhGBlY/oCOnX8UGPdii2Z87T/Qos+r7tEA9t80IByjJ18IxgL+ESDgo2QfMC3C IoWsUt7dWq3EDAubNQsW5hg6SNKn6fhYVCQThQlIx4tbcYakWYAiPykwSm4kIU2SvY2A Koa+SKzWp5h5p1rnjYueGZoe1GG38r00kWaY4gWDGDyh9YU3jPoeRy5oigzQIvvKpUFL 6a9Ig4grn1goqstvOemq/1/x1VmpKrYZa0ljO5mnX0uBO0+SlkxqPgO9ZhzhrE5B9V9h Aevw== X-Gm-Message-State: ANoB5plcVXOuMGABer0cBKvskcYSw1yuqppdaKFXrAbQGGPZE4y2RmsL zLuk5jOcm7opu3tjIqn4b47HdNWc0CWEpmE5 X-Google-Smtp-Source: AA0mqf731Uq25b8P7xlNj4NDIiWE32/ANCnqC2xJVLchA9+6HYv6jmG6jl4tlQFNm/ABo6ErGk/pHg== X-Received: by 2002:a17:906:4a9a:b0:7c1:2529:2760 with SMTP id x26-20020a1709064a9a00b007c125292760mr26778538eju.27.1671201229354; Fri, 16 Dec 2022 06:33:49 -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:49 -0800 (PST) To: libcamera-devel@lists.libcamera.org Date: Fri, 16 Dec 2022 14:33:44 +0000 Message-Id: <20221216143344.8177-4-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 3/3] pipeline: raspberrypi: Fix colour spaces by handling missing YCbCr information 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" In this patch we fix up colour spaces by adding the YCbCr information that is now not present for streams with an RGB output format. We need this information so that colour spaces are translated into the V4L2 ones that the Raspberry Pi hardware drivers will interpret correctly. Related to this, the YCbCr information is once again removed before the actual colour space is returned to us, so we have to be more careful about how we check that we got what we expected. Signed-off-by: David Plowman --- .../pipeline/raspberrypi/raspberrypi.cpp | 56 ++++++++++++++++++- 1 file changed, 54 insertions(+), 2 deletions(-) diff --git a/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp b/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp index 8569df17..f2d10d2a 100644 --- a/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp +++ b/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp @@ -357,6 +357,39 @@ RPiCameraConfiguration::RPiCameraConfiguration(const RPiCameraData *data) { } +static const std::vector validColorSpaces = { + ColorSpace::Sycc, + ColorSpace::Smpte170m, + ColorSpace::Rec709 +}; + +static std::optional fixColorSpace(const std::optional &colorSpace, + CameraConfiguration::Status &status) +{ + if (!colorSpace) + return std::nullopt; + + /* + * We prefer to restore any YCbCr encoding and range information that may have been + * removed from RGB streams. This ensures the colour spaces will be converted correctly + * into the colour spaces that the drivers handle, namely V4L2_COLORSPACE_JPEG, + * V4L2_COLORSPACE_SMPTE170M and V4L2_COLORSPACE_REC709. + * + * Luckily, the primaries and transfer function are enough for us to deduce exactly which + * ColorSpace was originally intended. + */ + for (const auto &cs : validColorSpaces) { + if (colorSpace->primaries == cs.primaries && + colorSpace->transferFunction == cs.transferFunction) + return cs; + } + + /* If nothing was matched, ask for sYCC. */ + LOG(RPI, Debug) << "No match for colour space " << colorSpace->toString(); + status = CameraConfiguration::Adjusted; + return ColorSpace::Sycc; +} + CameraConfiguration::Status RPiCameraConfiguration::validate() { Status status = Valid; @@ -533,7 +566,26 @@ CameraConfiguration::Status RPiCameraConfiguration::validate() V4L2DeviceFormat format; format.fourcc = dev->toV4L2PixelFormat(cfg.pixelFormat); format.size = cfg.size; - format.colorSpace = cfg.colorSpace; + /* + * Make sure the colour space is the one we want converted for our drivers, with + * the YCbCr information restored. status will be set to Adjusted if we didn't + * like the input colour space. + */ + format.colorSpace = fixColorSpace(cfg.colorSpace, status); + + /* + * When it comes back, RGB streams will have had the YCbCr information + * overwritten again, so let's figure out what we really expect to be + * returned. + */ + auto checkColorSpace = format.colorSpace; + if (checkColorSpace) { + const PixelFormatInfo &info = PixelFormatInfo::info(cfg.pixelFormat); + if (info.colourEncoding == PixelFormatInfo::ColourEncodingRGB) { + checkColorSpace->ycbcrEncoding = ColorSpace::YcbcrEncoding::None; + checkColorSpace->range = ColorSpace::Range::Full; + } + } LOG(RPI, Debug) << "Try color space " << ColorSpace::toString(cfg.colorSpace); @@ -542,7 +594,7 @@ CameraConfiguration::Status RPiCameraConfiguration::validate() if (ret) return Invalid; - if (cfg.colorSpace != format.colorSpace) { + if (checkColorSpace != format.colorSpace) { status = Adjusted; LOG(RPI, Debug) << "Color space changed from "