@@ -27,6 +27,7 @@
#include <libcamera/camera.h>
#include <libcamera/color_space.h>
#include <libcamera/control_ids.h>
+#include <libcamera/geometry.h>
#include <libcamera/pixel_format.h>
#include <libcamera/request.h>
#include <libcamera/stream.h>
@@ -1168,6 +1169,9 @@ CameraConfiguration::Status SimpleCameraConfiguration::validate()
pipeConfig_ = nullptr;
for (const SimpleCameraData::Configuration *pipeConfig : *configs) {
+ if (data_->processedRequested_ && pipeConfig->raw)
+ continue;
+
const Size &size = pipeConfig->captureSize;
if (size.width >= maxStreamSize.width &&
@@ -1209,37 +1213,60 @@ CameraConfiguration::Status SimpleCameraConfiguration::validate()
for (unsigned int i = 0; i < config_.size(); ++i) {
StreamConfiguration &cfg = config_[i];
+ /*
+ * If both processed and raw streams are requested, the pipe
+ * configuration is set up for the processed stream. The raw
+ * configuration needs to be compared against the capture format and
+ * size in such a case.
+ */
+ const bool rawStream = cfg.colorSpace == ColorSpace::Raw;
+ const bool sideRawStream = rawStream && data_->processedRequested_;
+
/* Adjust the pixel format and size. */
- auto it = std::find(pipeConfig_->outputFormats.begin(),
- pipeConfig_->outputFormats.end(),
- cfg.pixelFormat);
- if (it == pipeConfig_->outputFormats.end())
- it = pipeConfig_->outputFormats.begin();
-
- PixelFormat pixelFormat = *it;
- if (cfg.pixelFormat != pixelFormat) {
- LOG(SimplePipeline, Debug) << "Adjusting pixel format";
- cfg.pixelFormat = pixelFormat;
- if (cfg.colorSpace && cfg.colorSpace != ColorSpace::Raw)
+
+ if (!sideRawStream) {
+ auto it = std::find(pipeConfig_->outputFormats.begin(),
+ pipeConfig_->outputFormats.end(),
+ cfg.pixelFormat);
+ if (it == pipeConfig_->outputFormats.end())
+ it = pipeConfig_->outputFormats.begin();
+
+ PixelFormat pixelFormat = *it;
+
+ if (cfg.pixelFormat != pixelFormat) {
+ if (rawStream) {
+ LOG(SimplePipeline, Info)
+ << "Raw pixel format "
+ << cfg.pixelFormat
+ << " doesn't match any of the pipe output formats";
+ return Invalid;
+ }
+ LOG(SimplePipeline, Debug)
+ << "Adjusting pixel format from " << cfg.pixelFormat
+ << " to " << pixelFormat;
+ cfg.pixelFormat = pixelFormat;
+ if (cfg.colorSpace && cfg.colorSpace != ColorSpace::Raw)
+ cfg.colorSpace->adjust(pixelFormat);
+ status = Adjusted;
+ }
+
+ if (!cfg.colorSpace) {
+ const PixelFormatInfo &info = PixelFormatInfo::info(pixelFormat);
+ switch (info.colourEncoding) {
+ case PixelFormatInfo::ColourEncodingRGB:
+ cfg.colorSpace = ColorSpace::Srgb;
+ break;
+ case libcamera::PixelFormatInfo::ColourEncodingYUV:
+ cfg.colorSpace = ColorSpace::Sycc;
+ break;
+ default:
+ cfg.colorSpace = ColorSpace::Raw;
+ }
cfg.colorSpace->adjust(pixelFormat);
- status = Adjusted;
- }
- if (!cfg.colorSpace) {
- const PixelFormatInfo &info = PixelFormatInfo::info(pixelFormat);
- switch (info.colourEncoding) {
- case PixelFormatInfo::ColourEncodingRGB:
- cfg.colorSpace = ColorSpace::Srgb;
- break;
- case libcamera::PixelFormatInfo::ColourEncodingYUV:
- cfg.colorSpace = ColorSpace::Sycc;
- break;
- default:
- cfg.colorSpace = ColorSpace::Raw;
}
- cfg.colorSpace->adjust(pixelFormat);
}
- if (!pipeConfig_->outputSizes.contains(cfg.size)) {
+ if (!sideRawStream && !pipeConfig_->outputSizes.contains(cfg.size)) {
Size adjustedSize = pipeConfig_->captureSize;
/*
* The converter (when present) may not be able to output
@@ -1247,8 +1274,17 @@ CameraConfiguration::Status SimpleCameraConfiguration::validate()
* not guaranteed to be a valid output size. In such cases, use
* the smaller valid output size closest to the requested.
*/
- if (!pipeConfig_->outputSizes.contains(adjustedSize))
+ if (!pipeConfig_->outputSizes.contains(adjustedSize)) {
+ if (rawStream) {
+ LOG(SimplePipeline, Info)
+ << "Raw output size "
+ << cfg.size
+ << " doesn't match any of the pipe output sizes: "
+ << pipeConfig_->outputSizes;
+ return Invalid;
+ }
adjustedSize = adjustSize(cfg.size, pipeConfig_->outputSizes);
+ }
LOG(SimplePipeline, Debug)
<< "Adjusting size from " << cfg.size
<< " to " << adjustedSize;
@@ -1258,11 +1294,20 @@ CameraConfiguration::Status SimpleCameraConfiguration::validate()
/* \todo Create a libcamera core class to group format and size */
if (cfg.pixelFormat != pipeConfig_->captureFormat ||
- cfg.size != pipeConfig_->captureSize)
+ cfg.size != pipeConfig_->captureSize) {
+ if (rawStream) {
+ LOG(SimplePipeline, Info)
+ << "Raw output format " << cfg.pixelFormat
+ << " and size " << cfg.size
+ << " not matching pipe format " << pipeConfig_->captureFormat
+ << " and size " << pipeConfig_->captureSize;
+ return Invalid;
+ }
needConversion_ = true;
+ }
/* Set the stride, frameSize and bufferCount. */
- if (needConversion_) {
+ if (needConversion_ && !rawStream) {
std::tie(cfg.stride, cfg.frameSize) =
data_->converter_
? data_->converter_->strideAndFrameSize(cfg.pixelFormat,
SimpleCameraConfiguration::validate() looks for the best configuration. As part of enabling raw stream support, the method must consider raw streams in addition to the processed streams. If only a processed stream is requested, nothing changes. If only a raw stream is requested, the pixel format and output size may not be adjusted. The patch adds checks for this. If both processed and raw streams are requested, things get more complicated. The raw stream is expected to be passed through intact and all the adjustments are made for the processed streams. We select a pipe configuration for the processed streams. Note that with both processed and raw streams, the requested sizes must be mutually matching, including resizing due to debayer requirements. For example, the following `cam' setup is valid for imx219 cam -s role=viewfinder,width=1920,height=1080 \ -s role=raw,width=3280,height=2464 rather than cam -s role=viewfinder,width=1920,height=1080 \ -s role=raw,width=1920,height=1080 due to the resolution of 1924x1080 actually selected for debayering to 1920x1080. It is the application responsibility to select the right parameters for the raw stream. Setting up the right configurations is still not enough to make the raw streams working. Buffer handling must be changed in the simple pipeline, which is addressed in followup patches. Signed-off-by: Milan Zamazal <mzamazal@redhat.com> --- src/libcamera/pipeline/simple/simple.cpp | 103 ++++++++++++++++------- 1 file changed, 74 insertions(+), 29 deletions(-)