@@ -295,68 +295,135 @@ CameraConfiguration *PipelineHandlerVimc::generateConfiguration(Camera *camera,
int PipelineHandlerVimc::configure(Camera *camera, CameraConfiguration *config)
{
VimcCameraData *data = cameraData(camera);
- StreamConfiguration &cfg = config->at(0);
- int ret;
+ for (unsigned i = 0; i < config->size(); i++) {
+ StreamConfiguration &cfg = config->at(i);
+ const PixelFormatInfo &info = PixelFormatInfo::info(cfg.pixelFormat);
+ int ret;
+ if (info.isRaw(cfg.pixelFormat)) {
+ V4L2SubdeviceFormat subformat = {};
+ subformat.mbus_code = MEDIA_BUS_FMT_SGRBG8_1X8;
+ subformat.size = cfg.size;
+ ret = data->sensor_->setFormat(&subformat);
+ if (ret)
+ return ret;
+
+ V4L2DeviceFormat format = {};
+ format.fourcc = data->raw_->toV4L2PixelFormat(cfg.pixelFormat);
+ format.size = cfg.size;
+ ret = data->raw_->setFormat(&format);
+ if (ret)
+ return ret;
+
+ /*
+ * Formats have to be set on debayer, scaler, and RGB/YUB Capture
+ * otherwise the VIMC driver will fail pipeline validation
+ */
+
+ ret = data->debayer_->setFormat(0, &subformat);
+ if (ret)
+ return ret;
+
+ subformat.mbus_code = MEDIA_BUS_FMT_RGB888_1X24;
+ ret = data->debayer_->setFormat(1, &subformat);
+ if (ret)
+ return ret;
+
+ ret = data->scaler_->setFormat(0, &subformat);
+ if (ret)
+ return ret;
+
+ if (data->media_->version() >= KERNEL_VERSION(5, 6, 0)) {
+ Rectangle crop = {
+ .x = 0,
+ .y = 0,
+ .width = subformat.size.width,
+ .height = subformat.size.height,
+ };
+ ret = data->scaler_->setSelection(0, V4L2_SEL_TGT_CROP, &crop);
+ if (ret)
+ return ret;
+ }
- /* The scaler hardcodes a x3 scale-up ratio. */
- V4L2SubdeviceFormat subformat = {};
- subformat.mbus_code = MEDIA_BUS_FMT_SGRBG8_1X8;
- subformat.size = { cfg.size.width / 3, cfg.size.height / 3 };
+ subformat.mbus_code = MEDIA_BUS_FMT_RGB888_1X24;
+ subformat.size = { cfg.size.width * 3, cfg.size.height * 3 };
+ ret = data->scaler_->setFormat(1, &subformat);
+ if (ret)
+ return ret;
- ret = data->sensor_->setFormat(&subformat);
- if (ret)
- return ret;
+ format.fourcc = V4L2PixelFormat(V4L2_PIX_FMT_RGB24);
+ format.size = { cfg.size.width * 3, cfg.size.height * 3 };
+ ret = data->video_->setFormat(&format);
+ if (ret)
+ return ret;
- ret = data->debayer_->setFormat(0, &subformat);
- if (ret)
- return ret;
+ cfg.setStream(&data->rawStream_);
- subformat.mbus_code = pixelformats.find(cfg.pixelFormat)->second;
- ret = data->debayer_->setFormat(1, &subformat);
- if (ret)
- return ret;
+ } else {
+ /* The scaler hardcodes a x3 scale-up ratio. */
+ V4L2SubdeviceFormat subformat = {};
+ subformat.mbus_code = MEDIA_BUS_FMT_SGRBG8_1X8;
+ subformat.size = { cfg.size.width / 3, cfg.size.height / 3 };
+
+ ret = data->sensor_->setFormat(&subformat);
+ if (ret)
+ return ret;
+
+ ret = data->debayer_->setFormat(0, &subformat);
+ if (ret)
+ return ret;
+
+ subformat.mbus_code = pixelformats.find(cfg.pixelFormat)->second;
+ ret = data->debayer_->setFormat(1, &subformat);
+ if (ret)
+ return ret;
+
+ ret = data->scaler_->setFormat(0, &subformat);
+ if (ret)
+ return ret;
+
+ if (data->media_->version() >= KERNEL_VERSION(5, 6, 0)) {
+ Rectangle crop = {
+ .x = 0,
+ .y = 0,
+ .width = subformat.size.width,
+ .height = subformat.size.height,
+ };
+ ret = data->scaler_->setSelection(0, V4L2_SEL_TGT_CROP, &crop);
+ if (ret)
+ return ret;
+ }
- ret = data->scaler_->setFormat(0, &subformat);
- if (ret)
- return ret;
+ subformat.size = cfg.size;
+ ret = data->scaler_->setFormat(1, &subformat);
+ if (ret)
+ return ret;
- if (data->media_->version() >= KERNEL_VERSION(5, 6, 0)) {
- Rectangle crop{ 0, 0, subformat.size };
- ret = data->scaler_->setSelection(0, V4L2_SEL_TGT_CROP, &crop);
- if (ret)
- return ret;
+ V4L2DeviceFormat format = {};
+ format.fourcc = data->video_->toV4L2PixelFormat(cfg.pixelFormat);
+ format.size = cfg.size;
+ ret = data->video_->setFormat(&format);
+ if (ret)
+ return ret;
+
+ if (format.size != cfg.size ||
+ format.fourcc != data->video_->toV4L2PixelFormat(cfg.pixelFormat))
+ return -EINVAL;
+
+ /*
+ * Format has to be set on the raw capture video node, otherwise the
+ * vimc driver will fail pipeline validation.
+ */
+ format.fourcc = V4L2PixelFormat(V4L2_PIX_FMT_SGRBG8);
+ format.size = { cfg.size.width / 3, cfg.size.height / 3 };
+
+ ret = data->raw_->setFormat(&format);
+ if (ret)
+ return ret;
+
+ cfg.setStream(&data->rgbStream_);
+ }
}
- subformat.size = cfg.size;
- ret = data->scaler_->setFormat(1, &subformat);
- if (ret)
- return ret;
-
- V4L2DeviceFormat format = {};
- format.fourcc = data->video_->toV4L2PixelFormat(cfg.pixelFormat);
- format.size = cfg.size;
-
- ret = data->video_->setFormat(&format);
- if (ret)
- return ret;
-
- if (format.size != cfg.size ||
- format.fourcc != data->video_->toV4L2PixelFormat(cfg.pixelFormat))
- return -EINVAL;
-
- /*
- * Format has to be set on the raw capture video node, otherwise the
- * vimc driver will fail pipeline validation.
- */
- format.fourcc = V4L2PixelFormat(V4L2_PIX_FMT_SGRBG8);
- format.size = { cfg.size.width / 3, cfg.size.height / 3 };
-
- ret = data->raw_->setFormat(&format);
- if (ret)
- return ret;
-
- cfg.setStream(&data->rgbStream_);
-
return 0;
}
Configure the pads according to the configuration asked for. In case only one stream (RBG or RAW) is asked for, configurations still need to be set on the other entities in the pipeline. Signed-off-by: Kaaira Gupta <kgupta@es.iitr.ac.in> --- src/libcamera/pipeline/vimc/vimc.cpp | 175 ++++++++++++++++++--------- 1 file changed, 121 insertions(+), 54 deletions(-)