diff options
Diffstat (limited to 'users/flokli/ipu6-softisp/libcamera/0012-libcamera-pipeline-simple-enable-use-of-Soft-ISP-and.patch')
-rw-r--r-- | users/flokli/ipu6-softisp/libcamera/0012-libcamera-pipeline-simple-enable-use-of-Soft-ISP-and.patch | 302 |
1 files changed, 302 insertions, 0 deletions
diff --git a/users/flokli/ipu6-softisp/libcamera/0012-libcamera-pipeline-simple-enable-use-of-Soft-ISP-and.patch b/users/flokli/ipu6-softisp/libcamera/0012-libcamera-pipeline-simple-enable-use-of-Soft-ISP-and.patch new file mode 100644 index 000000000000..378a43604f9a --- /dev/null +++ b/users/flokli/ipu6-softisp/libcamera/0012-libcamera-pipeline-simple-enable-use-of-Soft-ISP-and.patch @@ -0,0 +1,302 @@ +From d64b0fca22ef25b8a14d7fc97dfab64eb1c4f21a Mon Sep 17 00:00:00 2001 +From: Andrey Konovalov <andrey.konovalov@linaro.org> +Date: Mon, 11 Mar 2024 15:15:16 +0100 +Subject: [PATCH 12/21] libcamera: pipeline: simple: enable use of Soft ISP and + Soft IPA + +To enable the Simple Soft ISP and Soft IPA for simple pipeline handler +configure the build with: + -Dpipelines=simple -Dipas=simple + +Also using the Soft ISP for the particular hardware platform must +be enabled in the supportedDevices[] table. + +If the pipeline uses Converter, Soft ISP and Soft IPA aren't +available. + +Tested-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org> # sc8280xp Lenovo x13s +Tested-by: Pavel Machek <pavel@ucw.cz> +Reviewed-by: Pavel Machek <pavel@ucw.cz> +Signed-off-by: Andrey Konovalov <andrey.konovalov@linaro.org> +Signed-off-by: Hans de Goede <hdegoede@redhat.com> +--- + src/libcamera/pipeline/simple/simple.cpp | 137 ++++++++++++++++++----- + 1 file changed, 109 insertions(+), 28 deletions(-) + +diff --git a/src/libcamera/pipeline/simple/simple.cpp b/src/libcamera/pipeline/simple/simple.cpp +index 78854ef8..c3ebb7b7 100644 +--- a/src/libcamera/pipeline/simple/simple.cpp ++++ b/src/libcamera/pipeline/simple/simple.cpp +@@ -34,6 +34,7 @@ + #include "libcamera/internal/device_enumerator.h" + #include "libcamera/internal/media_device.h" + #include "libcamera/internal/pipeline_handler.h" ++#include "libcamera/internal/software_isp/software_isp.h" + #include "libcamera/internal/v4l2_subdevice.h" + #include "libcamera/internal/v4l2_videodevice.h" + +@@ -185,17 +186,22 @@ struct SimplePipelineInfo { + * and the number of streams it supports. + */ + std::vector<std::pair<const char *, unsigned int>> converters; ++ /* ++ * Using Software ISP is to be enabled per driver. ++ * The Software ISP can't be used together with the converters. ++ */ ++ bool swIspEnabled; + }; + + namespace { + + static const SimplePipelineInfo supportedDevices[] = { +- { "dcmipp", {} }, +- { "imx7-csi", { { "pxp", 1 } } }, +- { "j721e-csi2rx", {} }, +- { "mxc-isi", {} }, +- { "qcom-camss", {} }, +- { "sun6i-csi", {} }, ++ { "dcmipp", {}, false }, ++ { "imx7-csi", { { "pxp", 1 } }, false }, ++ { "j721e-csi2rx", {}, false }, ++ { "mxc-isi", {}, false }, ++ { "qcom-camss", {}, true }, ++ { "sun6i-csi", {}, false }, + }; + + } /* namespace */ +@@ -274,6 +280,7 @@ public: + bool useConversion_; + + std::unique_ptr<Converter> converter_; ++ std::unique_ptr<SoftwareIsp> swIsp_; + + private: + void tryPipeline(unsigned int code, const Size &size); +@@ -281,6 +288,9 @@ private: + + void conversionInputDone(FrameBuffer *buffer); + void conversionOutputDone(FrameBuffer *buffer); ++ ++ void ispStatsReady(int dummy); ++ void setSensorControls(const ControlList &sensorControls); + }; + + class SimpleCameraConfiguration : public CameraConfiguration +@@ -332,6 +342,7 @@ public: + V4L2VideoDevice *video(const MediaEntity *entity); + V4L2Subdevice *subdev(const MediaEntity *entity); + MediaDevice *converter() { return converter_; } ++ bool swIspEnabled() { return swIspEnabled_; } + + protected: + int queueRequestDevice(Camera *camera, Request *request) override; +@@ -360,6 +371,7 @@ private: + std::map<const MediaEntity *, EntityData> entities_; + + MediaDevice *converter_; ++ bool swIspEnabled_; + }; + + /* ----------------------------------------------------------------------------- +@@ -509,6 +521,29 @@ int SimpleCameraData::init() + } + } + ++ /* ++ * Instantiate Soft ISP if this is enabled for the given driver and no converter is used. ++ */ ++ if (!converter_ && pipe->swIspEnabled()) { ++ swIsp_ = std::make_unique<SoftwareIsp>(pipe, sensor_->controls()); ++ if (!swIsp_->isValid()) { ++ LOG(SimplePipeline, Warning) ++ << "Failed to create software ISP, disabling software debayering"; ++ swIsp_.reset(); ++ } else { ++ /* ++ * \todo explain why SimpleCameraData::conversionInputDone() can't be directly ++ * connected to inputBufferReady signal. ++ */ ++ swIsp_->inputBufferReady.connect(pipe, [this](FrameBuffer *buffer) { ++ this->conversionInputDone(buffer); ++ }); ++ swIsp_->outputBufferReady.connect(this, &SimpleCameraData::conversionOutputDone); ++ swIsp_->ispStatsReady.connect(this, &SimpleCameraData::ispStatsReady); ++ swIsp_->setSensorControls.connect(this, &SimpleCameraData::setSensorControls); ++ } ++ } ++ + video_ = pipe->video(entities_.back().entity); + ASSERT(video_); + +@@ -599,12 +634,21 @@ void SimpleCameraData::tryPipeline(unsigned int code, const Size &size) + config.captureFormat = pixelFormat; + config.captureSize = format.size; + +- if (!converter_) { ++ ++ if (converter_) { ++ config.outputFormats = converter_->formats(pixelFormat); ++ config.outputSizes = converter_->sizes(format.size); ++ } else if (swIsp_) { ++ config.outputFormats = swIsp_->formats(pixelFormat); ++ config.outputSizes = swIsp_->sizes(pixelFormat, format.size); ++ if (config.outputFormats.empty()) { ++ /* Do not use swIsp for unsupported pixelFormat's: */ ++ config.outputFormats = { pixelFormat }; ++ config.outputSizes = config.captureSize; ++ } ++ } else { + config.outputFormats = { pixelFormat }; + config.outputSizes = config.captureSize; +- } else { +- config.outputFormats = converter_->formats(pixelFormat); +- config.outputSizes = converter_->sizes(format.size); + } + + configs_.push_back(config); +@@ -750,9 +794,9 @@ void SimpleCameraData::bufferReady(FrameBuffer *buffer) + } + + /* +- * The converter is in use. Requeue the internal buffer for +- * capture (unless the stream is being stopped), and complete +- * the request with all the user-facing buffers. ++ * The converter or Software ISP is in use. Requeue the internal ++ * buffer for capture (unless the stream is being stopped), and ++ * complete the request with all the user-facing buffers. + */ + if (buffer->metadata().status != FrameMetadata::FrameCancelled) + video_->queueBuffer(buffer); +@@ -798,9 +842,9 @@ void SimpleCameraData::bufferReady(FrameBuffer *buffer) + buffer->metadata().timestamp); + + /* +- * Queue the captured and the request buffer to the converter if format +- * conversion is needed. If there's no queued request, just requeue the +- * captured buffer for capture. ++ * Queue the captured and the request buffer to the converter or Software ++ * ISP if format conversion is needed. If there's no queued request, just ++ * requeue the captured buffer for capture. + */ + if (useConversion_) { + if (conversionQueue_.empty()) { +@@ -808,7 +852,11 @@ void SimpleCameraData::bufferReady(FrameBuffer *buffer) + return; + } + +- converter_->queueBuffers(buffer, conversionQueue_.front()); ++ if (converter_) ++ converter_->queueBuffers(buffer, conversionQueue_.front()); ++ else ++ swIsp_->queueBuffers(buffer, conversionQueue_.front()); ++ + conversionQueue_.pop(); + return; + } +@@ -834,6 +882,18 @@ void SimpleCameraData::conversionOutputDone(FrameBuffer *buffer) + pipe->completeRequest(request); + } + ++void SimpleCameraData::ispStatsReady([[maybe_unused]] int dummy) ++{ ++ swIsp_->processStats(sensor_->getControls({ V4L2_CID_ANALOGUE_GAIN, ++ V4L2_CID_EXPOSURE })); ++} ++ ++void SimpleCameraData::setSensorControls(const ControlList &sensorControls) ++{ ++ ControlList ctrls(sensorControls); ++ sensor_->setControls(&ctrls); ++} ++ + /* Retrieve all source pads connected to a sink pad through active routes. */ + std::vector<const MediaPad *> SimpleCameraData::routedSourcePads(MediaPad *sink) + { +@@ -1046,8 +1106,10 @@ CameraConfiguration::Status SimpleCameraConfiguration::validate() + /* Set the stride, frameSize and bufferCount. */ + if (needConversion_) { + std::tie(cfg.stride, cfg.frameSize) = +- data_->converter_->strideAndFrameSize(cfg.pixelFormat, +- cfg.size); ++ (data_->converter_) ? data_->converter_->strideAndFrameSize(cfg.pixelFormat, ++ cfg.size) ++ : data_->swIsp_->strideAndFrameSize(cfg.pixelFormat, ++ cfg.size); + if (cfg.stride == 0) + return Invalid; + } else { +@@ -1210,7 +1272,9 @@ int SimplePipelineHandler::configure(Camera *camera, CameraConfiguration *c) + inputCfg.stride = captureFormat.planes[0].bpl; + inputCfg.bufferCount = kNumInternalBuffers; + +- return data->converter_->configure(inputCfg, outputCfgs); ++ return (data->converter_) ? data->converter_->configure(inputCfg, outputCfgs) ++ : data->swIsp_->configure(inputCfg, outputCfgs, ++ data->sensor_->controls()); + } + + int SimplePipelineHandler::exportFrameBuffers(Camera *camera, Stream *stream, +@@ -1224,8 +1288,10 @@ int SimplePipelineHandler::exportFrameBuffers(Camera *camera, Stream *stream, + * whether the converter is used or not. + */ + if (data->useConversion_) +- return data->converter_->exportBuffers(data->streamIndex(stream), +- count, buffers); ++ return (data->converter_) ? data->converter_->exportBuffers(data->streamIndex(stream), ++ count, buffers) ++ : data->swIsp_->exportBuffers(data->streamIndex(stream), ++ count, buffers); + else + return data->video_->exportBuffers(count, buffers); + } +@@ -1270,10 +1336,18 @@ int SimplePipelineHandler::start(Camera *camera, [[maybe_unused]] const ControlL + } + + if (data->useConversion_) { +- ret = data->converter_->start(); +- if (ret < 0) { +- stop(camera); +- return ret; ++ if (data->converter_) { ++ ret = data->converter_->start(); ++ if (ret < 0) { ++ stop(camera); ++ return ret; ++ } ++ } else if (data->swIsp_) { ++ ret = data->swIsp_->start(); ++ if (ret < 0) { ++ stop(camera); ++ return ret; ++ } + } + + /* Queue all internal buffers for capture. */ +@@ -1289,8 +1363,13 @@ void SimplePipelineHandler::stopDevice(Camera *camera) + SimpleCameraData *data = cameraData(camera); + V4L2VideoDevice *video = data->video_; + +- if (data->useConversion_) +- data->converter_->stop(); ++ if (data->useConversion_) { ++ if (data->converter_) ++ data->converter_->stop(); ++ else if (data->swIsp_) { ++ data->swIsp_->stop(); ++ } ++ } + + video->streamOff(); + video->releaseBuffers(); +@@ -1452,6 +1531,8 @@ bool SimplePipelineHandler::match(DeviceEnumerator *enumerator) + } + } + ++ swIspEnabled_ = info->swIspEnabled; ++ + /* Locate the sensors. */ + std::vector<MediaEntity *> sensors = locateSensors(); + if (sensors.empty()) { +-- +2.43.2 + |