diff options
author | Nicholas Roth <nicholas@rothemail.net> | 2022-10-30 18:04:56 -0500 |
---|---|---|
committer | Jacopo Mondi <jacopo.mondi@ideasonboard.com> | 2023-10-18 13:06:44 +0000 |
commit | a7103ced3a6d9c56df839b1f2eab0780c56674f7 (patch) | |
tree | c43a2e01d60aef725baed4391f72c463021b682c /src/ipa/rpi/controller | |
parent | beaffa59a04ebabf17dee7b329ab570da14651b8 (diff) |
ipa: workaround libcxx duration limitationjmondi/android/vndk
A bug in libcxx [0] used by clang version 11.0.2 is prevalent when
building libcamera for Android SDK30. This has been fixed and
integrated upstream with [1].
As a workaround, directly cast libcamera::utils::Duration objects to
std::chrono::duration when dividing.
Alternatives evaluated:
Considered: Enable public inheritance of std::chrono::duration and
override operator/ in the class.
Outcome: Does not fix the original compiler error.
Considered: Enable public inheritance of std::chrono::duration and
override operator/ in the libcamera namespace.
Outcome: new compiler error:
ld.lld: error: duplicate symbol: libcamera::operator/
(libcamera::utils::Duration const&, libcamera::utils::Duration const&)
Considered: Use private inheritance of std::chrono::duration and
re-implement a pass-through version of each std::chrono::duration
operator within libcamera::utils::Duration and use template
metaprogramming to fix the division operator.
Outcome: Testing shows that this would introduce substantial
limitations, i.e. requring the Duration object to be on the LHS of any
arithmetic operation with other numeric types. This also substantially
increases implementation complexity.
Considered: Extract double values from libcamera::utils::Duration
objects and use those to divide.
Outcome: This creates substantial readability and unit-safety issues.
[0] https://github.com/llvm/llvm-project/issues/40475
[1] https://github.com/llvm/llvm-project/commit/efa6d803c624f9251d0ab7881122501bb9d27368
Bug: https://bugs.libcamera.org/show_bug.cgi?id=156
Signed-off-by: Nicholas Roth <nicholas@rothemail.net>
Diffstat (limited to 'src/ipa/rpi/controller')
-rw-r--r-- | src/ipa/rpi/controller/rpi/agc_channel.cpp | 11 | ||||
-rw-r--r-- | src/ipa/rpi/controller/rpi/lux.cpp | 3 |
2 files changed, 9 insertions, 5 deletions
diff --git a/src/ipa/rpi/controller/rpi/agc_channel.cpp b/src/ipa/rpi/controller/rpi/agc_channel.cpp index 3957dbc3..e856289a 100644 --- a/src/ipa/rpi/controller/rpi/agc_channel.cpp +++ b/src/ipa/rpi/controller/rpi/agc_channel.cpp @@ -473,7 +473,8 @@ void AgcChannel::prepare(Metadata *imageMetadata) Duration actualExposure = deviceStatus.shutterSpeed * deviceStatus.analogueGain; if (actualExposure) { - double digitalGain = totalExposureValue / actualExposure; + double digitalGain = std::chrono::duration(totalExposureValue) / + std::chrono::duration(actualExposure); LOG(RPiAgc, Debug) << "Want total exposure " << totalExposureValue; /* * Never ask for a gain < 1.0, and also impose @@ -925,7 +926,8 @@ void AgcChannel::divideUpExposure() } if (status_.fixedAnalogueGain == 0.0) { if (exposureMode_->gain[stage] * shutterTime >= exposureValue) { - analogueGain = exposureValue / shutterTime; + analogueGain = std::chrono::duration(exposureValue) / + std::chrono::duration(shutterTime); break; } analogueGain = exposureMode_->gain[stage]; @@ -941,10 +943,11 @@ void AgcChannel::divideUpExposure() */ if (!status_.fixedShutter && !status_.fixedAnalogueGain && status_.flickerPeriod) { - int flickerPeriods = shutterTime / status_.flickerPeriod; + int flickerPeriods = std::chrono::duration(shutterTime) / + std::chrono::duration(status_.flickerPeriod); if (flickerPeriods) { Duration newShutterTime = flickerPeriods * status_.flickerPeriod; - analogueGain *= shutterTime / newShutterTime; + analogueGain *= shutterTime / std::chrono::duration(newShutterTime); /* * We should still not allow the ag to go over the * largest value in the exposure mode. Note that this diff --git a/src/ipa/rpi/controller/rpi/lux.cpp b/src/ipa/rpi/controller/rpi/lux.cpp index 06625f3a..49a7af00 100644 --- a/src/ipa/rpi/controller/rpi/lux.cpp +++ b/src/ipa/rpi/controller/rpi/lux.cpp @@ -84,7 +84,8 @@ void Lux::process(StatisticsPtr &stats, Metadata *imageMetadata) double currentY = stats->yHist.interQuantileMean(0, 1); double gainRatio = referenceGain_ / currentGain; double shutterSpeedRatio = - referenceShutterSpeed_ / deviceStatus.shutterSpeed; + std::chrono::duration(referenceShutterSpeed_) / + std::chrono::duration(deviceStatus.shutterSpeed); double apertureRatio = referenceAperture_ / currentAperture; double yRatio = currentY * (65536 / stats->yHist.bins()) / referenceY_; double estimatedLux = shutterSpeedRatio * gainRatio * |