[libcamera-devel] [PATCH 2/5] libcamera: imx8-isi: Break out YUV format selection

Paul Elder paul.elder at ideasonboard.com
Thu Mar 2 12:35:17 CET 2023


On Sun, Jan 29, 2023 at 02:58:27PM +0100, Jacopo Mondi via libcamera-devel wrote:
> 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 <jacopo.mondi at ideasonboard.com>

Reviewed-by: Paul Elder <paul.elder at ideasonboard.com>

> ---
>  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<CameraSensor> sensor_;
>  	std::unique_ptr<V4L2Subdevice> 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<unsigned int> 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<unsigned int> 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<unsigned int> 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<Stream *> &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();
> -- 
> 2.39.0
> 


More information about the libcamera-devel mailing list