[libcamera-devel] [PATCH 2/5] libcamera: imx8-isi: Break out YUV format selection
Laurent Pinchart
laurent.pinchart at ideasonboard.com
Sun Mar 12 17:33:42 CET 2023
Hi Jacopo,
Thank you for the patch.
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: Laurent Pinchart <laurent.pinchart 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();
--
Regards,
Laurent Pinchart
More information about the libcamera-devel
mailing list