summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJacopo Mondi <jacopo.mondi@ideasonboard.com>2023-01-29 11:16:33 +0100
committerJacopo Mondi <jacopo.mondi@ideasonboard.com>2023-01-29 11:16:33 +0100
commit8e19093264b55e4bb469ddf2801fb923aa060713 (patch)
tree8eb85e2ac79ef8c96c63fde9931b53274ea9e991
parent39ee45815cfeceb2f1bf45b20b923d03757c1220 (diff)
libcamera: imx8-isi: Break out YUV format selection
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@ideasonboard.com>
-rw-r--r--src/libcamera/pipeline/imx8-isi/imx8-isi.cpp68
1 files changed, 68 insertions, 0 deletions
diff --git a/src/libcamera/pipeline/imx8-isi/imx8-isi.cpp b/src/libcamera/pipeline/imx8-isi/imx8-isi.cpp
index 72bc310d..5d0f86de 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,57 @@ unsigned int ISICameraData::getRawMediaBusFormat(PixelFormat *pixelFormat) const
return sensorCode;
}
+unsigned int ISICameraData::getYuvMediaBusFormat(PixelFormat *pixelFormat) const
+{
+ std::vector<unsigned int> mbusCodes = sensor_->mbusCodes();
+ std::vector<unsigned int> supportedCodes;
+
+ /*
+ * 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(), mbusCodes.end());
+
+ 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. */
+ for (unsigned int code : supportedCodes) {
+ if (PixelFormatInfo::info(*pixelFormat).colourEncoding ==
+ PixelFormatInfo::ColourEncodingYUV &&
+ (code == MEDIA_BUS_FMT_UYVY8_1X16 ||
+ code == MEDIA_BUS_FMT_YUV8_1X24))
+ return code;
+ else if (PixelFormatInfo::info(*pixelFormat).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 +507,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();