diff --git a/src/ipa/rpi/common/ipa_base.cpp b/src/ipa/rpi/common/ipa_base.cpp index 88040af32..359c5b9d6 100644 --- a/src/ipa/rpi/common/ipa_base.cpp +++ b/src/ipa/rpi/common/ipa_base.cpp @@ -12,21 +12,25 @@ #include #include + #include #include #include "controller/af_algorithm.h" #include "controller/af_status.h" #include "controller/agc_algorithm.h" +#include "controller/alsc_status.h" #include "controller/awb_algorithm.h" #include "controller/awb_status.h" #include "controller/black_level_status.h" #include "controller/ccm_algorithm.h" #include "controller/ccm_status.h" #include "controller/contrast_algorithm.h" +#include "controller/contrast_status.h" #include "controller/denoise_algorithm.h" #include "controller/hdr_algorithm.h" #include "controller/lux_status.h" +#include "controller/noise_status.h" #include "controller/sharpen_algorithm.h" #include "controller/statistics.h" #include "controller/sync_algorithm.h" @@ -82,6 +86,7 @@ const ControlInfoMap::Map ipaControls{ static_cast(defaultMaxFrameDuration.get()), Span{ { static_cast(defaultMinFrameDuration.get()), static_cast(defaultMinFrameDuration.get()) } }) }, + { &controls::EnableLensShadingCorrectionMapOutput, ControlInfo(false, true, false) }, { &controls::draft::NoiseReductionMode, ControlInfo(controls::draft::NoiseReductionModeValues) }, { &controls::rpi::StatsOutputEnable, ControlInfo(false, true, false) }, { &controls::rpi::CnnEnableInputTensor, ControlInfo(false, true, false) }, @@ -129,7 +134,7 @@ LOG_DEFINE_CATEGORY(IPARPI) namespace ipa::RPi { IpaBase::IpaBase() - : controller_(), frameLengths_(FrameLengthsQueueSize, 0s), statsMetadataOutput_(false), + : controller_(), frameLengths_(FrameLengthsQueueSize, 0s), lscMapsOutput_(false), statsMetadataOutput_(false), stitchSwapBuffers_(false), frameCount_(0), mistrustCount_(0), lastRunTimestamp_(0), firstStart_(true), flickerState_({ 0, 0s }), cnnEnableInputTensor_(false), awbEnabled_(true) { @@ -245,7 +250,6 @@ int32_t IpaBase::configure(const IPACameraSensorInfo &sensorInfo, const ConfigPa agcStatus.exposureTime = defaultExposureTime; agcStatus.analogueGain = defaultAnalogueGain; applyAGC(&agcStatus, ctrls); - } result->sensorControls = std::move(ctrls); @@ -795,8 +799,8 @@ static const std::map HdrModeTable = { void IpaBase::applyControls(const ControlList &controls) { - using RPiController::AgcAlgorithm; using RPiController::AfAlgorithm; + using RPiController::AgcAlgorithm; using RPiController::ContrastAlgorithm; using RPiController::DenoiseAlgorithm; using RPiController::HdrAlgorithm; @@ -1478,6 +1482,10 @@ void IpaBase::applyControls(const ControlList &controls) break; } + case controls::ENABLE_LENS_SHADING_CORRECTION_MAP_OUTPUT: + lscMapsOutput_ = ctrl.second.get(); + break; + case controls::rpi::STATS_OUTPUT_ENABLE: statsMetadataOutput_ = ctrl.second.get(); break; @@ -1762,6 +1770,43 @@ void IpaBase::reportMetadata(unsigned int ipaContext) static_cast(kpiInfo->dspRuntime) }); } + NoiseStatus *noiseStatus = rpiMetadata.getLocked("noise.status"); + if (noiseStatus) { + float noiseProfile[] = { static_cast(noiseStatus->noiseSlope), + static_cast(noiseStatus->noiseConstant) }; + + libcameraMetadata_.set(controls::NoiseProfile, noiseProfile); + } + + ContrastStatus *contrastStatus = rpiMetadata.getLocked("contrast.status"); + if (contrastStatus && contrastStatus->gammaCurve.size() > 0) { + std::vector contrast; + contrast.reserve(contrastStatus->gammaCurve.size() * 2); + + contrastStatus->gammaCurve.map([&](double x, double y) { + contrast.emplace_back(static_cast(x)); + contrast.emplace_back(static_cast(y)); + }); + libcameraMetadata_.set(controls::ToneCurve, contrast); + } + + if (lscMapsOutput_) { + AlscStatus *alscStatus = rpiMetadata.getLocked("alsc.status"); + if (alscStatus) { + uint32_t elements = alscStatus->cols * alscStatus->rows; + std::vector map(3 * elements); + + std::copy(alscStatus->r.begin(), alscStatus->r.end(), map.begin() + 0 * elements); + std::copy(alscStatus->g.begin(), alscStatus->g.end(), map.begin() + 1 * elements); + std::copy(alscStatus->b.begin(), alscStatus->b.end(), map.begin() + 2 * elements); + + uint32_t sizeTable[] = { 3, alscStatus->cols, alscStatus->rows }; + libcameraMetadata_.set(controls::LensShadingCorrectionMaps, map); + libcameraMetadata_.set(controls::LensShadingCorrectionMapSize, sizeTable); + libcameraMetadata_.set(controls::EnableLensShadingCorrectionMapOutput, true); + } + } + metadataReady.emit(libcameraMetadata_); } diff --git a/src/ipa/rpi/common/ipa_base.h b/src/ipa/rpi/common/ipa_base.h index 941a3b8f0..ff69f329e 100644 --- a/src/ipa/rpi/common/ipa_base.h +++ b/src/ipa/rpi/common/ipa_base.h @@ -68,6 +68,7 @@ class IpaBase : public IPARPiInterface std::deque frameLengths_; utils::Duration lastTimeout_; ControlList libcameraMetadata_; + bool lscMapsOutput_; bool statsMetadataOutput_; /* Remember the HDR status after a mode switch. */ diff --git a/src/ipa/rpi/common/meson.build b/src/ipa/rpi/common/meson.build index 73d2ee732..cb3555a80 100644 --- a/src/ipa/rpi/common/meson.build +++ b/src/ipa/rpi/common/meson.build @@ -5,7 +5,7 @@ rpi_ipa_common_sources = files([ ]) rpi_ipa_common_includes = [ - include_directories('..'), + include_directories('..','../..'), ] rpi_ipa_common_deps = [ diff --git a/src/ipa/rpi/controller/rpi/alsc.cpp b/src/ipa/rpi/controller/rpi/alsc.cpp index 4c852db04..0222da723 100644 --- a/src/ipa/rpi/controller/rpi/alsc.cpp +++ b/src/ipa/rpi/controller/rpi/alsc.cpp @@ -409,6 +409,9 @@ void Alsc::prepare(Metadata *imageMetadata) status.r = prevSyncResults_[0].data(); status.g = prevSyncResults_[1].data(); status.b = prevSyncResults_[2].data(); + status.cols = config_.tableSize.width; + status.rows = config_.tableSize.height; + imageMetadata->set("alsc.status", status); /* * Put the results in the global metadata as well. This will be used by diff --git a/src/libcamera/control_ids_core.yaml b/src/libcamera/control_ids_core.yaml index bde5c6b01..db115e643 100644 --- a/src/libcamera/control_ids_core.yaml +++ b/src/libcamera/control_ids_core.yaml @@ -1374,4 +1374,42 @@ controls: The nominal range is [-180, 180], where 0° leaves hues unchanged and the range wraps around continuously, with 180° == -180°. + - EnableLensShadingCorrectionMapOutput: + type: bool + direction: inout + description: | + Indicates if the lens shading correction maps should be set in frame- + metadata for each frame. Returns true if tables are successfully set. + + - LensShadingCorrectionMaps: + type: float + direction: out + description: | + A map giving the lens shading correction factors. Dimesnions of the + returned table is [number of channels, sizeX, sizeY] (planar tables) + size: [n] + + - LensShadingCorrectionMapSize: + type: uint32_t + direction: out + description: | + The number of channels/maps and the size of the lens shading correction + maps in pixels. E.g. [3, 32, 32] + size: [3] + + - ToneCurve: + type: float + direction: out + description: | + A profile tone curve to apply on linear RGB - as it seems it has the sRGB + gamma curve baked in. + size: [n] + + - NoiseProfile: + type: float + direction: out + description: | + The noise profile [Scale, Offset]. + size: [2] + ...