@@ -61,6 +61,7 @@ public:
std::tuple<unsigned int, unsigned int>
strideAndFrameSize(const PixelFormat &outputFormat, const Size &size);
+ uint32_t getPreferredInputStride(const PixelFormat &inputFormat, const Size &size);
int configure(const StreamConfiguration &inputCfg,
const std::vector<std::reference_wrapper<const StreamConfiguration>> &outputCfgs,
@@ -1542,6 +1542,11 @@ int SimplePipelineHandler::configure(Camera *camera, CameraConfiguration *c)
captureFormat.fourcc = videoFormat;
captureFormat.size = pipeConfig->captureSize;
+ uint32_t requested_bpl = 0;
+ if (data->swIsp_)
+ requested_bpl = data->swIsp_->getPreferredInputStride(videoFormat.toPixelFormat(), pipeConfig->captureSize);
+ captureFormat.planes[0].bpl = requested_bpl;
+
ret = video->setFormat(&captureFormat);
if (ret)
return ret;
@@ -1561,6 +1566,13 @@ int SimplePipelineHandler::configure(Camera *camera, CameraConfiguration *c)
return -EINVAL;
}
+ if (requested_bpl && captureFormat.planes[0].bpl != requested_bpl) {
+ LOG(SimplePipeline, Info)
+ << "Input buffer stride ignored by the driver. "
+ << "Requested " << requested_bpl
+ << ", got " << captureFormat.planes[0].bpl;
+ }
+
/* Configure the converter if needed. */
std::vector<std::reference_wrapper<const StreamConfiguration>> outputCfgs;
data->useConversion_ = config->needConversion();
@@ -103,6 +103,14 @@ Debayer::~Debayer()
* there is no valid output config
*/
+/**
+ * \fn uint32_t Debayer::getPreferredInputStride(const PixelFormat &inputFormat, const Size &size)
+ * Get the preferred input stride in bytes for the given input format and size
+ * \param[in] inputFormat The input format
+ * \param[in] size The input size (width and height in pixels)
+ * \return The preferred input stride in bytes
+ */
+
/**
* \fn void Debayer::process(uint32_t frame, FrameBuffer *input, FrameBuffer *output, DebayerParams params)
* \brief Process the bayer data into the requested format
@@ -46,6 +46,7 @@ public:
virtual std::tuple<unsigned int, unsigned int>
strideAndFrameSize(const PixelFormat &outputFormat, const Size &size) = 0;
+ virtual uint32_t getPreferredInputStride(const PixelFormat &inputFormat, const Size &size) { return 0; }
virtual void process(uint32_t frame, FrameBuffer *input, FrameBuffer *output, const DebayerParams ¶ms) = 0;
virtual int start() { return 0; }
@@ -20,6 +20,7 @@
#include <libcamera/formats.h>
+#include "libcamera/internal/formats.h"
#include "libcamera/internal/framebuffer.h"
#include "../glsl_shaders.h"
@@ -377,6 +378,12 @@ DebayerEGL::strideAndFrameSize(const PixelFormat &outputFormat, const Size &size
return std::make_tuple(stride, stride * size.height);
}
+uint32_t DebayerEGL::getPreferredInputStride(const PixelFormat &inputFormat, const Size &size)
+{
+ const PixelFormatInfo &info = PixelFormatInfo::info(inputFormat);
+ return info.stride(size.width, 0, 256);
+}
+
void DebayerEGL::setShaderVariableValues(const DebayerParams ¶ms)
{
/*
@@ -50,6 +50,7 @@ public:
std::vector<PixelFormat> formats(PixelFormat input) override;
std::tuple<unsigned int, unsigned int> strideAndFrameSize(const PixelFormat &outputFormat, const Size &size) override;
+ uint32_t getPreferredInputStride(const PixelFormat &inputFormat, const Size &size) override;
void process(uint32_t frame, FrameBuffer *input, FrameBuffer *output, const DebayerParams ¶ms) override;
int start() override;
@@ -255,6 +255,19 @@ SoftwareIsp::strideAndFrameSize(const PixelFormat &outputFormat, const Size &siz
return debayer_->strideAndFrameSize(outputFormat, size);
}
+/**
+ * Get the preferred input stride in bytes for the given input format and size
+ * \param[in] inputFormat The input format
+ * \param[in] size The input size (width and height in pixels)
+ * \return The preferred input stride in bytes
+ */
+uint32_t SoftwareIsp::getPreferredInputStride(const PixelFormat &inputFormat, const Size &size)
+{
+ ASSERT(debayer_);
+
+ return debayer_->getPreferredInputStride(inputFormat, size);
+}
+
/**
* \brief Configure the SoftwareIsp object according to the passed in parameters
* \param[in] inputCfg The input configuration
When using the GPU-ISP. This should increase the chances that input buffers can be imported and directly be used by the GPU as stride requirements are the most common reason for import fails. Notes: - 256 is already used for output buffers and known to work across most hardware. Unfortunately there is no API to query the optimal value from the GL driver. - The V4L2 API does not require drivers to honor stride request, thus we log those cases. Signed-off-by: Robert Mader <robert.mader@collabora.com> --- Follow-up to https://patchwork.libcamera.org/project/libcamera/list/?series=5965 --- .../libcamera/internal/software_isp/software_isp.h | 1 + src/libcamera/pipeline/simple/simple.cpp | 12 ++++++++++++ src/libcamera/software_isp/debayer.cpp | 8 ++++++++ src/libcamera/software_isp/debayer.h | 1 + src/libcamera/software_isp/debayer_egl.cpp | 7 +++++++ src/libcamera/software_isp/debayer_egl.h | 1 + src/libcamera/software_isp/software_isp.cpp | 13 +++++++++++++ 7 files changed, 43 insertions(+)