From patchwork Sun Jan 29 13:58:27 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 18219 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 2391DC3242 for ; Sun, 29 Jan 2023 13:58:52 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 33C54625F4; Sun, 29 Jan 2023 14:58:51 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1675000731; bh=Ic1Qc2h2V7lJTV/2HtJOoshbChZberdBeIK9bUVQduM=; 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=vY1fb9ztZ8cw5yJCM+BvIF8e3FAhuXPMi0UR4DiOTarQuz6ABfMJ4Hl2x9JBtdleW qwZ1QCEDnU37wSPZAsPt9DfpcZqzYNkVeGg8XunYJE2lnUCJzZB+XjL6hj69fRiAZA Fy9uWIH2KZ0VGBlhGJjZjdAysR6PdVdG4jCsF5VQWF7ag2Bivn108OTOFjsvZTRmTT Sp1jKbtr+2PzHT0p92+UWIM28lBmC7yu7WPcDspO+Z37YooZGyj9CV1VhHax5gNcKG Pp4wl0bwsNWcao4+6diajkL0fS7zjQe0a4Si3byP+GQg4j6pxJNc/r+ORowxq4TgGt Z3s33WadA5SfA== Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 092A2625DF for ; Sun, 29 Jan 2023 14:58:48 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="XsXNWHoB"; dkim-atps=neutral Received: from uno.localdomain (mob-5-90-54-203.net.vodafone.it [5.90.54.203]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 7FC71327; Sun, 29 Jan 2023 14:58:47 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1675000727; bh=Ic1Qc2h2V7lJTV/2HtJOoshbChZberdBeIK9bUVQduM=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=XsXNWHoBMHIDdDC5JSCLmSNYDUX+DMiR4s6VKL0GEklM7ksgv+JkJtocGXmgUmZrY f//aNPbQJx4YR1rJRFyoR8LZnn/Rnl766N4UD5fcN27zLnwbH5bT/mwgE4gcnxTQYp zmzXnR8yP/AWRvNecIMzNyhsoTtsxJyRzeAjmXZo= To: libcamera-devel@lists.libcamera.org Date: Sun, 29 Jan 2023 14:58:27 +0100 Message-Id: <20230129135830.27490-3-jacopo.mondi@ideasonboard.com> X-Mailer: git-send-email 2.39.0 In-Reply-To: <20230129135830.27490-1-jacopo.mondi@ideasonboard.com> References: <20230129135830.27490-1-jacopo.mondi@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 2/5] 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: Laurent Pinchart --- src/libcamera/pipeline/imx8-isi/imx8-isi.cpp | 76 ++++++++++++++++++++ 1 file changed, 76 insertions(+) diff --git a/src/libcamera/pipeline/imx8-isi/imx8-isi.cpp b/src/libcamera/pipeline/imx8-isi/imx8-isi.cpp index 72bc310d80ec..445fad32656c 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(PixelFormat *pixelFormat) const; std::unique_ptr sensor_; std::unique_ptr csis_; @@ -255,6 +256,65 @@ 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(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"; + *pixelFormat = {}; + + 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 */ @@ -455,6 +515,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();