@@ -1216,6 +1216,9 @@ CameraConfiguration::Status SimpleCameraConfiguration::validate()
* Then pick, among the possible configuration for the pixel format,
* the smallest sensor resolution that can accommodate all streams
* without upscaling.
+ *
+ * If both packed and unpacked Bayer capture formats are support prefer
+ * packed for lower memory usage and better software ISP performance.
*/
const SimpleCameraData::Configuration *maxPipeConfig = nullptr;
pipeConfig_ = nullptr;
@@ -1223,12 +1226,25 @@ CameraConfiguration::Status SimpleCameraConfiguration::validate()
for (const SimpleCameraData::Configuration *pipeConfig : *configs) {
const Size &captureSize = pipeConfig->captureSize;
const Size &maxOutputSize = pipeConfig->outputSizes.max;
+ bool curCfgPacked = false;
+ bool newCfgPacked = false;
+
+ if (pipeConfig_) {
+ BayerFormat curBayerFmt = BayerFormat::fromPixelFormat(pipeConfig_->captureFormat);
+ BayerFormat newBayerFmt = BayerFormat::fromPixelFormat(pipeConfig->captureFormat);
+ /* Only compare packed vs unpacked if both formats are Bayer */
+ if (curBayerFmt.isValid() && newBayerFmt.isValid()) {
+ curCfgPacked = curBayerFmt.packing == BayerFormat::Packing::CSI2;
+ newCfgPacked = newBayerFmt.packing == BayerFormat::Packing::CSI2;
+ }
+ }
if (maxOutputSize.width >= maxProcessedStreamSize.width &&
maxOutputSize.height >= maxProcessedStreamSize.height &&
captureSize.width >= maxRawStreamSize.width &&
captureSize.height >= maxRawStreamSize.height) {
- if (!pipeConfig_ || captureSize < pipeConfig_->captureSize)
+ if (!pipeConfig_ || captureSize < pipeConfig_->captureSize ||
+ (captureSize <= pipeConfig_->captureSize && !curCfgPacked && newCfgPacked))
pipeConfig_ = pipeConfig;
}
Some CSI2 receivers like the IPU6 isys can store e.g. 10 bpp Bayer formats in either CSI2 packed (5 bytes / 4 pixels) or unpacked (2 bytes / pixel) formats. Before this change the simple-pipeline handler would pick whatever format was enumerated first as capture format in this case. Which on IPU6 boards comes down to picking unpacked. Packed formats use less memory and typically perform better due to reduced RAM bandwidth requirements. E.g. on a Lenovo ThinkPad X1 Yoga Gen 8 with i7-1370P CPU and a ov2740 sensor running at full sensor (FHD) resolution, 3 consecutive benchmark runs using libcamera's software ISP's builtin Debayer benchmark gives the following results: Unpacked EGL us/frame: 6398 / 7393 / 7524 CSI2 pack EGL us/frame: 5682 / 5536 / 5634 Unpacked CPU us/frame: 7653 / 8147 / 8614 CSI2 pack CPU us/frame: 7183 / 7063 / 6318 Modify the simple pipeline handler to prefer the more performant CSI2 packed format when both formats are available. This also fixes a problem with unpacked formats on IPU6 where sometimes at the start of a stream the IPU6 isys CSI2 receiver may return a corrupt unpacked frame with high bits set which causes libcamera to crash with an out of bound array access as the software ISP code expects the high bits of unpacked formats to always be 0. Closes: https://gitlab.freedesktop.org/camera/libcamera/-/work_items/328 Signed-off-by: Hans de Goede <johannes.goede@oss.qualcomm.com> --- src/libcamera/pipeline/simple/simple.cpp | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-)