diff options
author | Florian Klink <flokli@flokli.de> | 2024-01-30T09·43+0200 |
---|---|---|
committer | flokli <flokli@flokli.de> | 2024-01-30T09·54+0000 |
commit | af9a8d372b24710bf7fc27c8e81244e1ca6d1658 (patch) | |
tree | df8bee03b202ec5081b9bd7e7b5d7b6ecdd28e1b /users/flokli/ipu6-softisp/libcamera/0015-libcamera-pipeline-simple-enable-use-of-Soft-ISP-and.patch | |
parent | b38be028d96ce107439f3323026270228a871a13 (diff) |
feat(users/flokli/ipu6-softisp): init r/7454
This code adds support for the ipu6 webcams via libcamera, based on the work in https://copr.fedorainfracloud.org/coprs/jwrdegoede/ipu6-softisp/. It's supposed to be included in your NixOS configuration imports. Change-Id: Ifb71999ad61161fa23506b97cb449f73fb1270e3 Reviewed-on: https://cl.tvl.fyi/c/depot/+/10709 Tested-by: BuildkiteCI Reviewed-by: flokli <flokli@flokli.de> Autosubmit: flokli <flokli@flokli.de>
Diffstat (limited to 'users/flokli/ipu6-softisp/libcamera/0015-libcamera-pipeline-simple-enable-use-of-Soft-ISP-and.patch')
-rw-r--r-- | users/flokli/ipu6-softisp/libcamera/0015-libcamera-pipeline-simple-enable-use-of-Soft-ISP-and.patch | 243 |
1 files changed, 243 insertions, 0 deletions
diff --git a/users/flokli/ipu6-softisp/libcamera/0015-libcamera-pipeline-simple-enable-use-of-Soft-ISP-and.patch b/users/flokli/ipu6-softisp/libcamera/0015-libcamera-pipeline-simple-enable-use-of-Soft-ISP-and.patch new file mode 100644 index 000000000000..f639a3b74c93 --- /dev/null +++ b/users/flokli/ipu6-softisp/libcamera/0015-libcamera-pipeline-simple-enable-use-of-Soft-ISP-and.patch @@ -0,0 +1,243 @@ +From ad61052d9aea1f1af6aaef9ce7e5d447c595187c Mon Sep 17 00:00:00 2001 +From: Andrey Konovalov <andrey.konovalov@linaro.org> +Date: Tue, 12 Dec 2023 02:02:37 +0300 +Subject: [PATCH 15/25] 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/simple -Dipas=simple/simple + +If the pipeline uses Converter, Soft ISP and Soft IPA aren't +available. + +Configuring the build with just: + -Dpipelines=simple +makes it to work like before - Soft ISP and Soft IPA aren't used. + +Signed-off-by: Andrey Konovalov <andrey.konovalov@linaro.org> +Signed-off-by: Hans de Goede <hdegoede@redhat.com> +Tested-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org> # sc8280xp Lenovo x13s +Tested-by: Pavel Machek <pavel@ucw.cz> +--- + src/libcamera/pipeline/simple/simple.cpp | 111 ++++++++++++++++++----- + 1 file changed, 89 insertions(+), 22 deletions(-) + +diff --git a/src/libcamera/pipeline/simple/simple.cpp b/src/libcamera/pipeline/simple/simple.cpp +index fa298746..c76510c2 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.h" + #include "libcamera/internal/v4l2_subdevice.h" + #include "libcamera/internal/v4l2_videodevice.h" + +@@ -274,6 +275,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 +283,9 @@ private: + + void conversionInputDone(FrameBuffer *buffer); + void conversionOutputDone(FrameBuffer *buffer); ++ ++ void ispStatsReady(int dummy); ++ void setSensorControls(const ControlList &sensorControls); + }; + + class SimpleCameraConfiguration : public CameraConfiguration +@@ -509,6 +514,25 @@ int SimpleCameraData::init() + } + } + ++ /* ++ * Create SoftwareIsp unconditionally if no converter is used ++ * - to be revisited ++ */ ++ if (!converter_) { ++ swIsp_ = SoftwareIspFactoryBase::create(pipe, sensor_->controls()); ++ if (!swIsp_) { ++ LOG(SimplePipeline, Warning) ++ << "Failed to create software ISP, disabling software debayering"; ++ swIsp_.reset(); ++ } else { ++ swIsp_->inputBufferReady.connect(this, &SimpleCameraData::conversionInputDone); ++ swIsp_->outputBufferReady.connect(this, &SimpleCameraData::conversionOutputDone); ++ swIsp_->ispStatsReady.connect(this, &SimpleCameraData::ispStatsReady); ++ ++ swIsp_->getSignalSetSensorControls().connect(this, &SimpleCameraData::setSensorControls); ++ } ++ } ++ + video_ = pipe->video(entities_.back().entity); + ASSERT(video_); + +@@ -599,12 +623,20 @@ void SimpleCameraData::tryPipeline(unsigned int code, const Size &size) + config.captureFormat = pixelFormat; + config.captureSize = format.size; + +- if (!converter_) { +- config.outputFormats = { pixelFormat }; +- config.outputSizes = config.captureSize; +- } else { ++ 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; + } + + configs_.push_back(config); +@@ -750,9 +782,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 +830,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 +840,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 +870,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) + { +@@ -1016,8 +1064,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 { +@@ -1180,7 +1230,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, +@@ -1194,8 +1246,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); + } +@@ -1240,10 +1294,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. */ +@@ -1259,8 +1321,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(); +-- +2.43.0 + |