From patchwork Thu Apr 27 14:47:36 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 18568 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 CA580C0DA4 for ; Thu, 27 Apr 2023 14:48:04 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id BF7B7627E5; Thu, 27 Apr 2023 16:48:03 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1682606883; bh=u4yhRYsQGr3RW1k3tBHwyYwm5pcIqohWWED5ANd4P9M=; 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=ij/WXMutXDBqTWexCjObxCbHknwf8QBs3+UHuOlJLw0LIORQwWs2KB+UAvuMRHTVv FHh7Oc5dX9EzgltsDlo1xE65ekqf9gGmm8cXGEup7lgs6N+7UthS2DmvkzYNukZ0Cu HgmrZDxeVH+R04WvJXGE2IdGuiGKDv7OOngLN8Inh9Xm/t4gbe75yFD8rpFGnTeDHK vWeRhG4bJKs+f6jz+Xyb72YZ1M+9Gelj0wRlnYIzftRNmJfThQKLG3fRaBmFJcyLCy ze2dSj+Szxy7+8kpLTHRNtvWif4FR5VGc77gm5cME3c426gBwl50DBbtiGFR68iwq+ uDnfPIaIITfsA== 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 CFB3D627E3 for ; Thu, 27 Apr 2023 16:47:59 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="oT2846KN"; dkim-atps=neutral Received: from uno.lan (unknown [IPv6:2001:b07:5d2e:52c9:1cf0:b3bc:c785:4625]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 6BA03802; Thu, 27 Apr 2023 16:47:47 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1682606867; bh=u4yhRYsQGr3RW1k3tBHwyYwm5pcIqohWWED5ANd4P9M=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=oT2846KNYoG+ZXRFKaccjsGvc7vnoBHtzh0jHdfH3Qnracp+H2RnGU2YoT8eEEapS EJddwA9QXBzlKUuRncSXrXrhX6zVnZlvVm3b2Op2lugr47OxbDe3jNU4uofsKU3inJ 9XMCB5VdXaM6FmyVhhSEUC6gTwxJl4VF2d95dYCM= To: libcamera-devel@lists.libcamera.org Date: Thu, 27 Apr 2023 16:47:36 +0200 Message-Id: <20230427144740.64075-3-jacopo.mondi@ideasonboard.com> X-Mailer: git-send-email 2.40.0 In-Reply-To: <20230427144740.64075-1-jacopo.mondi@ideasonboard.com> References: <20230427144740.64075-1-jacopo.mondi@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v3 2/6] libcamera: imx8-isi: Break out YUV format selection 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: Jacopo Mondi via libcamera-devel From: Jacopo Mondi Reply-To: Jacopo Mondi Cc: Jacopo Mondi Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" As per the RAW format selection, the media bus format selection procedure relies on the direct association of PixelFormat and media bus code in the formatsMap_ map. As the ISI can generate YUV and RGB formats from any non-Bayer media bus format, break out the YUV/RGB media bus format selection to a separate function. The newly introduced getYuvMediaBusFormat() tests a list of known-supported media bus formats against the list of media bus formats supported by the sensor and tries to prefer media bus codes with the same encoding as the requested PixelFormat. Use the newly introduced function in ISICameraConfiguration::validateYuv() to make sure the sensor can produce a YUV/RGB media bus format. Signed-off-by: Jacopo Mondi Reviewed-by: Paul Elder Reviewed-by: Daniel Scally Tested-by: Daniel Scally Reviewed-by: Laurent Pinchart --- src/libcamera/pipeline/imx8-isi/imx8-isi.cpp | 75 ++++++++++++++++++++ 1 file changed, 75 insertions(+) diff --git a/src/libcamera/pipeline/imx8-isi/imx8-isi.cpp b/src/libcamera/pipeline/imx8-isi/imx8-isi.cpp index d124f1cc96d3..148f108d630f 100644 --- a/src/libcamera/pipeline/imx8-isi/imx8-isi.cpp +++ b/src/libcamera/pipeline/imx8-isi/imx8-isi.cpp @@ -60,6 +60,7 @@ public: } unsigned int getRawMediaBusFormat(PixelFormat *pixelFormat) const; + unsigned int getYuvMediaBusFormat(const PixelFormat &pixelFormat) const; std::unique_ptr sensor_; std::unique_ptr csis_; @@ -259,6 +260,64 @@ unsigned int ISICameraData::getRawMediaBusFormat(PixelFormat *pixelFormat) const return sensorCode; } +/* + * Get a YUV/RGB media bus format from which the ISI can produce a processed + * stream, preferring codes with the same colour encoding as the requested + * pixelformat. + * + * If the sensor does not provide any YUV/RGB media bus format the ISI cannot + * generate any processed pixel format as it cannot debayer. + */ +unsigned int ISICameraData::getYuvMediaBusFormat(const PixelFormat &pixelFormat) const +{ + std::vector mbusCodes = sensor_->mbusCodes(); + + /* + * The ISI can produce YUV/RGB pixel formats from any non-RAW Bayer + * media bus formats. + * + * Keep the list in sync with the mxc_isi_bus_formats[] array in + * the ISI driver. + */ + std::vector yuvCodes = { + MEDIA_BUS_FMT_UYVY8_1X16, + MEDIA_BUS_FMT_YUV8_1X24, + MEDIA_BUS_FMT_RGB565_1X16, + MEDIA_BUS_FMT_RGB888_1X24, + }; + + std::sort(mbusCodes.begin(), mbusCodes.end()); + std::sort(yuvCodes.begin(), yuvCodes.end()); + + std::vector supportedCodes; + std::set_intersection(mbusCodes.begin(), mbusCodes.end(), + yuvCodes.begin(), yuvCodes.end(), + std::back_inserter(supportedCodes)); + + if (supportedCodes.empty()) { + LOG(ISI, Warning) << "Cannot find a supported YUV/RGB format"; + + return 0; + } + + /* Prefer codes with the same encoding as the requested pixel format. */ + const PixelFormatInfo &info = PixelFormatInfo::info(pixelFormat); + for (unsigned int code : supportedCodes) { + if (info.colourEncoding == PixelFormatInfo::ColourEncodingYUV && + (code == MEDIA_BUS_FMT_UYVY8_1X16 || + code == MEDIA_BUS_FMT_YUV8_1X24)) + return code; + + if (info.colourEncoding == PixelFormatInfo::ColourEncodingRGB && + (code == MEDIA_BUS_FMT_RGB565_1X16 || + code == MEDIA_BUS_FMT_RGB888_1X24)) + return code; + } + + /* Otherwise return the first found code. */ + return supportedCodes[0]; +} + /* ----------------------------------------------------------------------------- * Camera Configuration */ @@ -459,6 +518,22 @@ ISICameraConfiguration::validateYuv(std::set &availableStreams, { CameraConfiguration::Status status = Valid; + StreamConfiguration &yuvConfig = config_[0]; + PixelFormat yuvPixelFormat = yuvConfig.pixelFormat; + + /* + * Make sure the sensor can produce a compatible YUV/RGB media bus + * format. If the sensor can only produce RAW Bayer we can only fail + * here as we can't adjust to anything but RAW. + */ + unsigned int yuvMediaBusCode = data_->getYuvMediaBusFormat(yuvPixelFormat); + if (!yuvMediaBusCode) { + LOG(ISI, Error) << "Cannot adjust pixelformat " + << yuvConfig.pixelFormat; + return Invalid; + } + + /* Adjust all the other streams. */ for (const auto &[i, cfg] : utils::enumerate(config_)) { LOG(ISI, Debug) << "Stream " << i << ": " << cfg.toString();